Compare commits

..

130 Commits

Author SHA1 Message Date
durch 3f9bfb4bb4 Put circulating supply back as Option 2022-06-15 00:03:13 +02:00
Mark Sinclair e6a00ad8d4 Merge pull request #1363 from nymtech/feature/reorder-delegation-table-columns
reorder delegation table columns
2022-06-14 18:40:14 +01:00
fmtabbara 815416bb41 allow sign in with enter key + create key listener hook 2022-06-14 17:21:07 +01:00
fmtabbara f6f0e68fac reorder delegation table columns 2022-06-14 16:52:45 +01:00
Mark Sinclair 70b23063c8 Update changelog and increment wallet version number for next release 2022-06-14 16:47:21 +01:00
Jędrzej Stuczyński 25a9fc85d2 Chore/lock file cleanup (#1360)
* Removed redundant lock files + updated cw3 and cw4 cw-storage-plus

addresses #1313

* Removed redundant lock files for clients

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

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

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

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

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

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

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

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

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

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

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-14 15:38:22 +01:00
Gala 81bbb61dac enabling discord icon (#1319) 2022-06-13 15:56:07 +01:00
Gala e768d99e3d Explorer: Moving where is displayed the delegators number (#1341)
* moving the delegators number

* changing column header and styles order

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

* fix(wallet): style

* feat(wallet): remove useless color

* feat(wallet): some style changes

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

* feat(wallet): fix padding
2022-06-13 11:03:16 +02:00
Jon Häggblad 77d16d34af changelog: added entry for nym-connect 2022-06-10 19:41:34 +02:00
Jon Häggblad 9e8868f357 Merge pull request #1338 from nymtech/feature/hrycyszynvpn 2022-06-10 16:44:16 +02:00
Jon Häggblad 64fdf5a270 Merge remote-tracking branch 'origin/develop' into feature/hrycyszynvpn 2022-06-10 16:13:21 +02:00
Jon Häggblad c17d65380c connect: disable keybase notfication 2022-06-10 16:12:40 +02:00
Mark Sinclair 00e234a754 Network Explorer upgrades and fixes (#1343)
* Upgrade storybook and add mock for Tauri `api/app`

* Upgrade Network Explorer to React Router 6

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

* Migration staking supply (#1327)

* Staking supply to params migration

* Include into migration entrypoint

* StateParams merge

* Add changelog

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

* verloc: make shutdown handler not optional

* verloc: logging without explicit target

* rustmt

* mixnode: note about rocket

* verloc: remove accidental duplicate block

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

* Require build arguments in validator docker build

* docker-compose.yml: Remove unused WASMD_COMMIT_HASH argument

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

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

Update QA vars

fmt

re-map coin type for qa

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

clean up

fmt

Delegation components

Show delegation story on paper

Remove actions header from delegations list

Add copy to clipboard for delegation list node ids

Move tooltip

Modals

Extract modal styles

Fix exports

Rewards summary and redeem modal

Factor out simple modal

Delegations actions modals: delegate, delegate more, undelegate

Coin mark and move logo stories

Rust types

React components handle currency

Form field to enter and display an Identity Key

Fix up build order

Update README

Flat buttons

End adornment

Currency form field

Add more props

Export components

Add currency and mixnode fields

Group stories into folders and add flow

Change exports from shared packages to stop webpack bundling issues

Fix logo import

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

Delegations views and routes for wallet

Delegations list show pending delegations and undelegations

wip - delegations page status

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

Add more interstitial states and confirmation modals

Copy change

Move config to inside source tree

Fix up `Console` typings

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

wip

wip

wip

ts-rs: remove old files

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

ts-rs: remove old files

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

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

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

wip

update type imports and fix some lint errors

update packages

update type imports

update type imports

update type imports

update type imports

start pulling out use of  minorMajor and majorMinor

update type imports

update import

Add missing types generated by ts-rs

fix types

Adding denom to account

type updates

Handle micro currency denoms

Fix type conversion mistake

Add clean target

eslint: formatting

Update React currency components to use `MajorCurrencyAmount`

Add separators and extra props to currency components

replace currency mapper with denom returning from service

Adjust type while generation is broken

start integrating new CurrencyFormField component

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

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

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

fix conflict

fix delegations form

start fixing validation

type update

remove console log

tidy up

remove more unused types

remove more unused types

Fix `Coin` denom to be `minor`

Fix up to minor_cosmos_coin

Fix up send

Remove `Coin` type

Fix up exported types

start delegation UI

more UI work

close actions modal on action select

update label

fix old delegateion form

minor updates

undo change to currency in stringD

Fix up types

Add feature flag for generating typescript
Generate types behind feature flag

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

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

Update generations target

Add missing types for generation

Generate typescript types

reorder imports

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

update types

Add delegate with everything

Add get block to nymd client

More conversions

Get a big list of delegations with lots of stuff

Add `avg_uptime_percent`

component api updates

ui updates and fixes

Add delegation history and pending events

Fix up addition

Fix up pending delegation event types

Filter pending delegation events

add history and pending events

set total delegations

rebase

fix breaking type change on delegate page

Fix mixnode mapping

Add back refresh and set periodic refresh

upgrade to react router 6

Add logging
Export new types for gas and transactions

increase container size!

add sendtx type

update onOK to return MAjorCurrencyAmount

align table items

display dash if amount not availble

work on delegate and undelegate

Make serializable

More types

Fix up errors

align item icon

type updates

Add operation to get all pending delegation/undelegation events

Fix up logging

Add more logging

Fix undelegate error

get pending delegation events

remove unused import

* Fix rebase errors

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

* get wallet balance after transactions

* fix duplicate key

* use token pool selector

* update wording

* Created nymd internal coin

* spell delegations correctly!

* Additional From implementations plus a constructor

* try_add

* Changed client API to use the new coin type

* CoinConverter trait

* Made wallet compilable with the recent changes

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

* Fixed validator api

* integrate modal divider with modal component

* handle undelegation of locked tokens

* only return events table if there are events

* Fixed up tests and clippy

* Refactored  missed coin-generic API methods

* changelog

* refresh on network or client details change

* Bunch of  temporary workaround to have wallet working-ish

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

* CHANGELOG

* Sort CHANGELOG lines

* PR comments

* allow sorting of pending events

* fix lint errors

* handle page overflow

* handle reedem and vesting redeem requests

* set up compound rewards

* refresh locked tokens on page load

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

* update validation for hostname (prevent leading spaces)

* add compound success case

* display est fee until new simulations are used

* fix up coin validation

* tommy fixes

* Show app version at bottom of nav

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

* Update change log

Co-authored-by: tommy <tommyvez@protonmail.com>
Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Co-authored-by: durch <durch@users.noreply.github.com>
2022-06-09 17:05:17 +01:00
Bogdan-Ștefan Neacşu fbdf31b879 Feature/split stats service (#1328)
* Replace client address with service address

* Copy over the server parts of the statistics server

* Separate API in module

* Rename struct

* Add insertion endpoint

* Remove unused code from network requester

* Box big rocket error

* Remove the feature-specific code

* Construct http req

* Clippy + Cargo.lock update

* Re-added needed sqlx feature

* Wrap http req in ordered msg

* Add http headers

* Move common api functionality into the separate crate

* Make stats server address configurable, especially for testing

* Update changelog

* Fix clippy

* Help command update
2022-06-09 16:58:51 +03:00
Jon Häggblad e9aa75ccac wallet: fix clippy (#1334) 2022-06-09 14:35:44 +02:00
Jon Häggblad be938cf4f0 client/native: tidy some logging (#1320)
* client/native: some logging refinement

* client/native: fix pedantic clippy warn

* client/native: another pedantic clippy warn

* rustfmt
2022-06-08 21:51:00 +02:00
Bogdan-Ștefan Neacşu 12412d32e6 Panic early if re-init with new gateway (#1322)
* Panic early if re-init with new gateway

* Update CHANGELOG
2022-06-08 14:07:17 +03:00
Bogdan-Ștefan Neacşu fb5193163e Remove coconut debugging code (#1321) 2022-06-08 12:08:12 +03:00
Jędrzej Stuczyński c13d3ab15d Updated cosmwasm dependencies to 1.0.0 (#1318)
* Updated cosmwasm dependencies to 1.0.0

* changelog
2022-06-07 12:55:10 +01:00
Bogdan-Ștefan Neacşu f655a9d8c6 Replace default network with provided network (#1317) 2022-06-07 14:44:48 +03:00
gala1234 73a2fd68c6 Merge branch 'develop' of github.com:nymtech/nym into develop 2022-06-07 13:18:33 +02:00
gala1234 ca16dc6d66 Revert "Adding discord icon"
This reverts commit 24d3089458.
2022-06-07 13:17:15 +02:00
Jon Häggblad d5c456a370 wallet: additional wallet test (#1312) 2022-06-07 13:16:00 +02:00
gala1234 24d3089458 Adding discord icon 2022-06-07 13:14:16 +02:00
Tommy Verrall b020251b62 Merge pull request #1309 from nymtech/feature-219-explorer-small-changes
Explorer: Feature 219 explorer small changes
2022-06-07 11:31:29 +01:00
Jon Häggblad f15ecdda06 mixnode: graceful shutdown on ctrl-c (#1304)
* mixnode: add graceful notification to most tasks

* Add note about remaining work

* task/shutdown: add shutdown timer

* changelog: add entry for shutdown

* mixnode: revert some temp changes

* common/task: make sure to use latest tokio
2022-06-07 11:41:58 +02:00
Raphaël Walther 7a74bb9ad5 Fixed unused variables in test (#1311) 2022-06-07 09:47:59 +01:00
gala1234 67625fe768 explorer: move stake-sat column in node list 2022-06-07 09:40:55 +02:00
gala1234 858ef7b3f9 cleaning 2022-06-06 16:49:04 +02:00
gala1234 c7dd48edbb remove delegators number column on node list and hardcode 2022-06-06 16:47:30 +02:00
gala1234 7c6d8daba2 Merge branch 'develop' into feature-219-explorer-small-changes 2022-06-06 16:40:22 +02:00
vnpmid d8fed178aa Upgrade to tokio 1.19.1, tokio-util 0.7.3, tokio-stream 0.1.9, tokio-test 0.4.2 (#1305)
* Upgrade to tokio 1.19.1, tokio-util 0.7.3, tokio-stream 0.1.9, tokio-test 0.4.2

* Tokio-util 0.7.3 handle_done_delaying, handle_expired_ack_timer

* Upgrade to tokio 1.19.1, tokio-util 0.7.3, tokio-stream 0.1.9, tokio-test 0.4.2
2022-06-06 14:38:01 +01:00
Drazen Urch 27a4a44717 Claim and compound reward wallet endpoints (#1302)
* Add claim and compound wallet endpoints, proc_macro to generate execute and simulate

* CHANGELOG

* Sort CHANGELOG lines

* PR comments
2022-06-06 14:19:36 +02:00
Drazen Urch 459db5718e Set probability to 1 if less nodes then the limit (#1306)
* Set probability to 1 if less nodes then the limit

* Check both sets independantly
2022-06-06 14:19:24 +02:00
durch 1bdaab6c97 Fix underflow in rewards estimation 2022-06-06 14:17:59 +02:00
Tommy Verrall d3fe80c875 Merge pull request #1303 from nymtech/feature-225-delegation-number
explorer: implement SummedDelegations endpoint and display value on f…
2022-06-06 10:04:32 +01:00
Raphaël Walther ec799cf17c Add sccache to wallet workflow 2022-06-02 18:59:23 +02:00
Bogdan-Ștefan Neacşu 5f7b3db9a4 Feature/spend coconut (#1261)
* Add coconut verifier structure for coconut protocol in gateway

* Add endpoint for validator-api cred verification

* Remove unused signature field

* Register new endpoint

* Improve validator-api config handling

* Aggregate verif result from all apis

* Simplify aggregate functions

* Verify cred on apis correctly

* Introduced coconut bandwidth contract to validator client

* Fix rebase double import

* Fix clippy on non-coconut

* Add multisig contract address to validator client

* Refactor Credential struct

* Do bincode magic in the coconut interface

* Implement serialization for credential and remove bindcode

* Fix clippy and don't remove dkg

* Client release funds proposal

* Add wrapper for blinded serial number

Also compare theta with a blinded serial number (in base 58 form)
for future double spend protection.

* Only post blinded serial number to blockchain

* Validator api propose credential spending

* Fix wallet

* Gateway calls proposal creation

* Query for proposal in verify coconut

* Remove db from git

* Verify against proposal description

* Validator apis vote based on verification of cred

* Fix wallet fmt

* Execute the release of funds

* Fix translation between token and bytes

* Update CHANGELOG
2022-06-02 16:54:59 +03:00
gala1234 6a929af584 Merge branch 'develop' into feature-225-delegation-number 2022-06-01 15:39:57 +02:00
Tommy Verrall a5759ab227 Merge pull request #1300 from nymtech/feature-224-add-stake-saturation
explorer: adding stake saturation o node list
2022-06-01 14:38:24 +01:00
Raphaël Walther 960305b54e Modify runner label 2022-06-01 15:20:40 +02:00
Raphaël Walther 066aded9bb Modify runner label 2022-06-01 14:54:22 +02:00
gala1234 a6a5ffce68 explorer: implement SummedDelegations endpoint and display value on frontend 2022-06-01 14:18:20 +02:00
Jon Häggblad 802334b37e explorer-api: add endpoint for summed delegations (#1299)
* explorer-api: add endpoint for summed delegations

* changelog: add note
2022-06-01 13:36:34 +02:00
Jon Häggblad c79ee5052f validator-api: add detailed mixnode bond endpoints (#1294)
* validator-api: add mixnodes-detailed endpoint

* validator-api: add detailed variants of active and rewarded set

* explorer-api: cache as mixnode bond detailed

* explorer-api: add in stake-saturation in response

* changelog: update

* rustfmt

* validator-api: rename to MixNodeBondResponse

* validator-api: cache MixNodeBondResponse instead

* validator-api: rename to MixNodeBondAnnotated

* validator-client: fix unused warning

* explorer-api: remove unnecessary clone

* rustfmt
2022-06-01 13:02:16 +02:00
Tommy Verrall fc985da2f7 Merge pull request #1301 from nymtech/feature/update-geo-ip
Update to use new geo_locate stats
2022-06-01 11:43:11 +01:00
tommy b7d3333ff8 Update to use new geo_locate stats 2022-06-01 11:19:54 +01:00
gala1234 41f4097628 explorer: remove hardcoded part 2022-06-01 11:29:02 +02:00
gala1234 e21216419d Merge branch 'develop' into feature-224-add-stake-saturation 2022-06-01 11:05:02 +02:00
Tommy Verrall 79e6dc5e77 Merge pull request #1298 from nymtech/fix/dotenv
Clippy warnings on .env file
2022-06-01 08:24:25 +01:00
tommy 266b050c82 merge 2022-05-31 17:30:12 +01:00
tommy 7609e7084c clippy warnings 2022-05-31 17:27:32 +01:00
Tommy Verrall 0faed6085e Merge pull request #1297 from nymtech/fix/dotenv
Allow .env not to be present
2022-05-31 17:05:54 +01:00
tommy c513d59724 allow dotenv not to be present 2022-05-31 17:01:02 +01:00
Jędrzej Stuczyński 9f51c60bac Wallet simulate bandaid (#1296)
* Removed Add/Sub that somehow got brought back in a merge

* Created 'get_old_and_incorrect_hardcoded_fee' to make wallet as it did before

* Brought back all Operation variants just in case
2022-05-31 15:52:26 +01:00
Jędrzej Stuczyński 58b5389ed9 Consolidate validator-client coin (#1295)
* Created nymd internal coin

* Additional From implementations plus a constructor

* try_add

* Changed client API to use the new coin type

* CoinConverter trait

* Made wallet compilable with the recent changes

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

* Fixed validator api

* Fixed up tests and clippy

* Refactored  missed coin-generic API methods

* changelog
2022-05-31 14:10:19 +01:00
Drazen Urch 2f4be6dedc Add claim reward to vesting and mixnet contract (#1292)
* Add claim reward to vesting contract

* Add compound and claim methods to nymd client

* Add TrackReward message

* CHANGELOG
2022-05-31 11:06:10 +02:00
Drazen Urch 189b83e769 Fix uptime integer division, change lambda and sigma from ticked to regular (#1284)
* Add more data to reward-estimate response

* Fix uptime integer division error

* typo

* Reify tuple response

* Fix uptime calculation

* Use lambda and sigma instead of ticked versions for delegator and operator rewards calculation

* Changelog
2022-05-31 11:03:28 +02:00
Jon Häggblad 83f80f094c wallet: tweak log text to avoid confusion 2022-05-31 09:06:57 +02:00
gala1234 c65c1ef7cb re-organising node list columns and validators column name change 2022-05-30 13:03:25 +02:00
Jędrzej Stuczyński 2dfbd2f714 Removed rustfmt.toml file and adjusted wallet formatting (#1293) 2022-05-30 10:57:49 +01:00
gala1234 296ed47ba4 explorer: fixing colour 2022-05-26 12:32:21 +02:00
gala1234 7dd11d4602 explorer: stake saturation colour 2022-05-26 12:25:43 +02:00
gala1234 e7a8221005 Merge branch 'develop' into feature-219-explorer-small-changes 2022-05-26 12:05:28 +02:00
gala1234 02a34b2592 Merge branch 'develop' into feature-224-add-stake-saturation 2022-05-26 12:04:26 +02:00
gala1234 6afecbddfa explorer: mook stake saturation response from API 2022-05-26 12:02:44 +02:00
gala1234 1ee1d4ebf7 explorer: altering api response to make ui work 2022-05-26 11:32:57 +02:00
Mark Sinclair 41d5c05a76 Merge pull request #1290 from nymtech/fix/build-dev-wallet-windows
add run-all package to build dev wallet on windows
2022-05-26 09:57:09 +01:00
Bogdan-Ștefan Neacşu a9422a32ed Make stats in network requester opt-in (#1288) 2022-05-26 11:33:25 +03:00
Jędrzej Stuczyński 177f1deefe Feature/gas simulation improvements (#1291)
* Updated cosmrs

* Simpler fmt::Display for Operation

* Adjusted GasPrice parsing test due to changes in Denom FromStr impl

* Removed direct dependency on cosmrs in the wallet

* Removed TryFrom<GasPrice> for Coin as it didn't make much sense

* disgusting workaround for providing serde for fee

* NymdError improvements

* Ability to simulate "send"

* Removed needless conversions

* Changedi nterface to "normal" send to account for new fee

* Removed outdated imports in tests

* Removal of 'Operation' enum

* Implemented simulate endpoints for all other txs
2022-05-26 09:26:49 +01:00
Tommy Verrall a1f633d225 add run-all package to build dev wallet on windows 2022-05-25 17:13:01 +01:00
gala1234 780c6041ef bond, stake and pledge re-wording 2022-05-25 14:09:09 +02:00
gala1234 e9280f2c17 swap bond to stake and pledge to bond 2022-05-25 10:45:08 +02:00
gala1234 ddd84295c4 remove layer column 2022-05-25 10:11:36 +02:00
Jon Häggblad 60526fdb90 wallet: check against importing same mnemonic twice (#1283) 2022-05-24 15:13:45 +02:00
Jędrzej Stuczyński 7d82fe0c0d Feature/various improvements (#1282)
* Added abci::Data field to ExecuteResult

* optional serde support for ed25519 keys

* optional serde support for x25519 keys

* actually calling dotenv at validator API startup

* Added STATE_DENOM network specific constant

* unit test fixes
2022-05-24 09:52:00 +01:00
Jon Häggblad db09870352 Remove unused deps 2022-05-23 15:52:46 +02:00
Jon Häggblad d703e160e3 Start socks5 client in task 2022-05-23 15:49:21 +02:00
Bogdan-Ștefan Neacşu d7920a4f50 Use remote source for stats provider address (#1281) 2022-05-23 16:33:47 +03:00
durch 71cfdb4d07 Add vesting glossary 2022-05-23 13:25:20 +02:00
Jon Häggblad 1d6dabd0b5 Remove some tracing in socks5 client 2022-05-20 16:11:47 +02:00
Jon Häggblad 4ce68fd6f2 Merge branch 'develop' into feature/hrycyszynvpn 2022-05-20 16:07:11 +02:00
Jon Häggblad 83f6fbec5d Remove things not needed 2022-05-20 15:42:16 +02:00
Jon Häggblad d87479f28c Uncomment code and try build 2022-05-18 16:06:48 +02:00
Jon Häggblad 59db03a55d Fix build on linux 2022-05-11 11:20:20 +02:00
Jędrzej Stuczyński 5db7f7e0bc Fixing some dependencies 2022-04-29 14:39:42 +01:00
Mark Sinclair 2422f090cc wip: add client 2022-04-27 14:30:17 +01:00
Mark Sinclair 1362d8a3eb Bump rust version and make dependencies match wallet 2022-04-26 17:14:10 +01:00
Mark Sinclair 40274689e3 Add pinned versions from develop 2022-04-26 14:50:48 +01:00
Mark Sinclair 3f9d6b2f1c wip 2022-04-26 14:50:47 +01:00
666 changed files with 47944 additions and 17168 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build:
runs-on: [ self-hosted, custom-linux-exoscale ]
runs-on: [ self-hosted, custom-linux ]
# Enable sccache via environment variable
env:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
+1 -1
View File
@@ -4,7 +4,7 @@ on: workflow_dispatch
jobs:
build:
runs-on: [ self-hosted, custom-linux-exoscale ]
runs-on: [ self-hosted, custom-linux ]
# Enable sccache via environment variable
env:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
+59
View File
@@ -0,0 +1,59 @@
name: CI for nym-connect
on:
push:
paths:
- 'nym-connect/**'
defaults:
run:
working-directory: nym-connect
jobs:
build:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install Yarn
run: npm install -g yarn
- run: yarn
continue-on-error: true
- name: Set environment from the example
run: cp .env.sample .env
- run: yarn storybook:build
- name: Deploy branch to CI www
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "nym-connect/storybook-static/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/nym-connect-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
# - name: Keybase - Send Notification
# env:
# NYM_NOTIFICATION_KIND: nym-connect
# NYM_PROJECT_NAME: "nym-connect"
# NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
# NYM_CI_WWW_LOCATION: "nym-connect-${{ env.GITHUB_REF_SLUG }}"
# GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
# GIT_BRANCH: "${GITHUB_REF##*/}"
# KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
# KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
# KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
# KEYBASE_NYM_CHANNEL: "ci-nym-connect"
# IS_SUCCESS: "${{ job.status == 'success' }}"
# uses: docker://keybaseio/client:stable-node
# with:
# args: .github/workflows/support-files/notifications/entry_point.sh
@@ -66,6 +66,7 @@ jobs:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
ADMIN_ADDRESS: ${{ secrets.WALLET_ADMIN_ADDRESS }}
run: yarn && yarn build
- name: Upload to release based on tag name
@@ -44,6 +44,7 @@ jobs:
env:
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
ADMIN_ADDRESS: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
with:
@@ -65,6 +65,7 @@ jobs:
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
ADMIN_ADDRESS: ${{ secrets.WALLET_ADMIN_ADDRESS }}
run: yarn build
- name: Upload to release based on tag name
@@ -3,7 +3,7 @@ require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly'],
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect'],
};
/**
@@ -0,0 +1,29 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
async function addToContextAndValidate(context) {
if (!context.env.NYM_CI_WWW_LOCATION) {
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
}
if (!context.env.NYM_CI_WWW_BASE) {
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.IS_SUCCESS === 'true'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
return template(context);
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -0,0 +1,11 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
> 🔴 **FAILURE** :cry:
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -0,0 +1,11 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View storybook:** https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}/
> ✅ **SUCCESS**
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
+3 -1
View File
@@ -10,7 +10,9 @@ on:
jobs:
build:
runs-on: [ self-hosted, custom-linux-exoscale ]
runs-on: [ self-hosted, custom-linux ]
env:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
+53 -9
View File
@@ -1,34 +1,78 @@
# Changelog
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- wallet: require password to switch accounts
- wallet: add simple CLI tool for decrypting and recovering the wallet file.
- wallet: added support for multiple accounts ([#1265])
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- mixnet-contract: Replace all naked `-` with `saturating_sub`.
- validator-api: add Swagger to document the REST API ([#1249]).
- nym-connect: initial proof-of-concept of a UI around the socks5 client was added.
- all: added network compilation target to `--help` (or `--version`) commands ([#1256]).
- network-requester: send traffic statistics from all network requesters and receive it in a special network-requester that aggregates the data and exposes it via a rest API ([#1267], [#1278]).
- explorer-api: learned how to sum the delegations by owner in a new endpoint.
- gateway: Added gateway coconut verifications and validator-api communication for double spending protection ([#1261])
- mixnet-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- mixnet-contract: Replace all naked `-` with `saturating_sub`.
- mixnet-contrat: Added staking_supply field to ContractStateParams.
- network-explorer-ui: Upgrade to React Router 6
- rewarding: replace circulating supply with staking supply in reward calculations ([#1324])
- validator-api: add `estimated_node_profit` and `estimated_operator_cost` to `reward-estimate` endpoint ([#1284])
- validator-api: add detailed mixnode bond endpoints, and explorer-api makes use of that data to append stake saturation.
- validator-api: add Swagger to document the REST API ([#1249]).
- validator-api: Added new endpoints for coconut spending flow and communications with coconut & multisig contracts ([#1261])
- vesting-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- network-statistics: a new mixnet service that aggregates and exposes anonymized data about mixnet services ([#1328])
### Fixed
- vesting-contract: replaced `checked_sub` with `saturating_sub` to fix the underflow in `get_vesting_tokens` ([#1275])
- mixnet-contract: `estimated_delegator_reward` calculation ([#1284])
- mixnet-contract: delegator and operator rewards use lambda and sigma instead of lambda_ticked and sigma_ticked ([#1284])
- mixnet-contract: removed `expect` in `query_delegator_reward` and queries containing invalid proxy address should now return a more human-readable error ([#1257])
- mixnet-contract: replaced integer division with fixed for performance calculations ([#1284])
- mixnet-contract: Under certain circumstances nodes could not be unbonded ([#1255](https://github.com/nymtech/nym/issues/1255)) ([#1258])
- mixnode, gateway: attempting to determine reconnection backoff to persistently failing mixnode could result in a crash ([#1260])
- mixnode: the mixnode learned how to shutdown gracefully.
- vesting-contract: replaced `checked_sub` with `saturating_sub` to fix the underflow in `get_vesting_tokens` ([#1275])
- native & socks5 clients: fail early when clients try to re-init with a different gateway, which is not supported yet ([#1322])
- validator: fixed local docker-compose setup to work on Apple M1 ([#1329])
### Changed
- validator-client: created internal `Coin` type that replaces coins from `cosmrs` and `cosmwasm` for API entrypoints [[#1295]]
- all: updated all `cosmwasm`-related dependencies to `1.0.0` and `cw-storage-plus` to `0.13.4` [[#1318]]
- network-requester: allow to voluntarily store and send statistical data about the number of bytes the proxied server serves ([#1328])
[#1258]: https://github.com/nymtech/nym/pull/1258
[#1249]: https://github.com/nymtech/nym/pull/1249
[#1256]: https://github.com/nymtech/nym/pull/1256
[#1257]: https://github.com/nymtech/nym/pull/1257
[#1258]: https://github.com/nymtech/nym/pull/1258
[#1260]: https://github.com/nymtech/nym/pull/1260
[#1261]: https://github.com/nymtech/nym/pull/1261
[#1265]: https://github.com/nymtech/nym/pull/1265
[#1267]: https://github.com/nymtech/nym/pull/1267
[#1275]: https://github.com/nymtech/nym/pull/1275
[#1278]: https://github.com/nymtech/nym/pull/1278
[#1284]: https://github.com/nymtech/nym/pull/1284
[#1292]: https://github.com/nymtech/nym/pull/1292
[#1295]: https://github.com/nymtech/nym/pull/1295
[#1302]: https://github.com/nymtech/nym/pull/1302
[#1318]: https://github.com/nymtech/nym/pull/1318
[#1322]: https://github.com/nymtech/nym/pull/1322
[#1324]: https://github.com/nymtech/nym/pull/1324
[#1328]: https://github.com/nymtech/nym/pull/1328
[#1329]: https://github.com/nymtech/nym/pull/1329
## [nym-wallet-v1.0.5](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.5) (2022-06-14)
- wallet: add simple CLI tool for decrypting and recovering the wallet file.
- wallet: added support for multiple accounts ([#1265])
- wallet: compound and claim reward endpoints for operators and delegators ([#1302])
- wallet: require password to switch accounts
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- wallet: new delegation and rewards UI
- wallet: show version in nav bar
- wallet: contract admin route put back
- wallet: staking_supply field to StateParams
- wallet: show transaction hash for redeeming or compounding rewards
## [nym-wallet-v1.0.4](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.4) (2022-05-04)
Generated
+302 -203
View File
@@ -218,9 +218,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64ct"
version = "1.5.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
[[package]]
name = "binascii"
@@ -245,7 +245,7 @@ checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f"
dependencies = [
"bs58",
"hmac 0.11.0",
"k256 0.10.4",
"k256",
"once_cell",
"pbkdf2",
"rand_core 0.6.3",
@@ -664,8 +664,8 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc347c19eb5b940f396ac155822caee6662f850d97306890ac3773ed76c90c5a"
dependencies = [
"prost",
"prost-types",
"prost 0.9.0",
"prost-types 0.9.0",
"tonic",
"tonic-build",
"tracing-core",
@@ -683,7 +683,7 @@ dependencies = [
"futures",
"hdrhistogram",
"humantime 2.1.0",
"prost-types",
"prost-types 0.9.0",
"serde",
"serde_json",
"thread_local",
@@ -695,12 +695,6 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "const-oid"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
[[package]]
name = "const-oid"
version = "0.7.1"
@@ -761,60 +755,29 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "cosmos-sdk-proto"
version = "0.9.0"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0254ffee603f5301d6a66963d9e1cc5091479c22e2e925e1f7689c8027a0828"
checksum = "f109fe191e73898d74b8020c50f86018364ad19bc30318aa074616c382b52856"
dependencies = [
"prost",
"prost-types",
"tendermint-proto",
]
[[package]]
name = "cosmos-sdk-proto"
version = "0.9.0"
source = "git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation#911fbe1236cfed591783ccef01018f7ccc97c496"
dependencies = [
"prost",
"prost-types",
"prost 0.10.3",
"prost-types 0.10.1",
"tendermint-proto",
]
[[package]]
name = "cosmrs"
version = "0.4.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "505ea048e9ff2f906d6b954f9f8157d903ca468bfb301d906b40ecc25ba6838d"
checksum = "8413275b23cb5a0734d9d1e3e33f0b5b94547c1e94776dbc3149dbf46588a533"
dependencies = [
"bip32",
"cosmos-sdk-proto 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ecdsa 0.13.4",
"cosmos-sdk-proto",
"ecdsa",
"eyre",
"getrandom 0.2.6",
"k256 0.10.4",
"prost",
"prost-types",
"rand_core 0.6.3",
"serde",
"serde_json",
"subtle-encoding",
"tendermint",
"thiserror",
]
[[package]]
name = "cosmrs"
version = "0.4.1"
source = "git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation#911fbe1236cfed591783ccef01018f7ccc97c496"
dependencies = [
"bip32",
"cosmos-sdk-proto 0.9.0 (git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation)",
"ecdsa 0.13.4",
"eyre",
"getrandom 0.2.6",
"k256 0.10.4",
"prost",
"prost-types",
"k256",
"prost 0.10.3",
"prost-types 0.10.1",
"rand_core 0.6.3",
"serde",
"serde_json",
@@ -826,31 +789,31 @@ dependencies = [
[[package]]
name = "cosmwasm-crypto"
version = "1.0.0-beta8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e70111e9701c3ec43bfbff0e523cd4cb115876b4d3433813436dd0934ee962"
checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd"
dependencies = [
"digest 0.9.0",
"ed25519-zebra",
"k256 0.9.6",
"k256",
"rand_core 0.6.3",
"thiserror",
]
[[package]]
name = "cosmwasm-derive"
version = "1.0.0-beta8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58bc2ad5d86be5f6068833f63e20786768db6890019c095dd7775232184fb7b3"
checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4"
dependencies = [
"syn",
]
[[package]]
name = "cosmwasm-std"
version = "1.0.0-beta8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915ca82bd944f116f3a9717481f3fa657e4a73f28c4887288761ebb24e6fbe10"
checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195"
dependencies = [
"base64",
"cosmwasm-crypto",
@@ -904,7 +867,6 @@ dependencies = [
"bip39",
"cfg-if 0.1.10",
"clap 3.1.8",
"coconut-bandwidth-contract-common",
"coconut-interface",
"credential-storage",
"credentials",
@@ -938,7 +900,7 @@ version = "0.1.0"
dependencies = [
"bls12_381 0.5.0",
"coconut-interface",
"cosmrs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cosmrs",
"crypto",
"network-defaults",
"rand 0.7.3",
@@ -1069,18 +1031,6 @@ dependencies = [
"x25519-dalek",
]
[[package]]
name = "crypto-bigint"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03"
dependencies = [
"generic-array 0.14.5",
"rand_core 0.6.3",
"subtle 2.4.1",
"zeroize",
]
[[package]]
name = "crypto-bigint"
version = "0.3.2"
@@ -1181,21 +1131,58 @@ dependencies = [
"byteorder",
"digest 0.9.0",
"rand_core 0.5.1",
"serde",
"subtle 2.4.1",
"zeroize",
]
[[package]]
name = "cw-storage-plus"
version = "0.13.2"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35"
checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a"
dependencies = [
"cosmwasm-std",
"schemars",
"serde",
]
[[package]]
name = "cw-utils"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e"
dependencies = [
"cosmwasm-std",
"schemars",
"serde",
"thiserror",
]
[[package]]
name = "cw3"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f871854338a54c7bb094d16ffe17212b93b146d9659dbce4c9402a9b77e240ef"
dependencies = [
"cosmwasm-std",
"cw-utils",
"schemars",
"serde",
]
[[package]]
name = "cw4"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4476d6a7c13c46ed9ff260bd0e1cf648dc37b13f483822e1ff2a431f0f6ee52"
dependencies = [
"cosmwasm-std",
"cw-storage-plus",
"schemars",
"serde",
]
[[package]]
name = "darling"
version = "0.13.4"
@@ -1241,22 +1228,13 @@ dependencies = [
"num_cpus",
]
[[package]]
name = "der"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
dependencies = [
"const-oid 0.6.2",
]
[[package]]
name = "der"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c"
dependencies = [
"const-oid 0.7.1",
"const-oid",
]
[[package]]
@@ -1399,26 +1377,14 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28"
[[package]]
name = "ecdsa"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372"
dependencies = [
"der 0.4.5",
"elliptic-curve 0.10.6",
"hmac 0.11.0",
"signature",
]
[[package]]
name = "ecdsa"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9"
dependencies = [
"der 0.5.1",
"elliptic-curve 0.11.12",
"der",
"elliptic-curve",
"rfc6979",
"signature",
]
@@ -1469,22 +1435,6 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "elliptic-curve"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b"
dependencies = [
"crypto-bigint 0.2.11",
"ff 0.10.1",
"generic-array 0.14.5",
"group 0.10.0",
"pkcs8 0.7.6",
"rand_core 0.6.3",
"subtle 2.4.1",
"zeroize",
]
[[package]]
name = "elliptic-curve"
version = "0.11.12"
@@ -1492,8 +1442,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6"
dependencies = [
"base16ct",
"crypto-bigint 0.3.2",
"der 0.5.1",
"crypto-bigint",
"der",
"ff 0.11.0",
"generic-array 0.14.5",
"group 0.11.0",
@@ -1597,6 +1547,14 @@ dependencies = [
"uint",
]
[[package]]
name = "execute"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "explorer-api"
version = "1.0.1"
@@ -1604,6 +1562,7 @@ dependencies = [
"chrono",
"humantime-serde",
"isocountry",
"itertools",
"log",
"mixnet-contract-common",
"network-defaults",
@@ -1980,7 +1939,6 @@ dependencies = [
name = "gateway-requests"
version = "0.1.0"
dependencies = [
"bincode",
"bs58",
"coconut-interface",
"credentials",
@@ -2136,7 +2094,7 @@ dependencies = [
"indexmap",
"slab",
"tokio",
"tokio-util 0.7.1",
"tokio-util 0.7.3",
"tracing",
]
@@ -2384,11 +2342,12 @@ dependencies = [
"headers",
"http",
"hyper",
"hyper-tls",
"native-tls",
"hyper-rustls",
"rustls-native-certs",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tower-service",
"webpki",
]
[[package]]
@@ -2627,18 +2586,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "k256"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea"
dependencies = [
"cfg-if 1.0.0",
"ecdsa 0.12.4",
"elliptic-curve 0.10.6",
"sha2",
]
[[package]]
name = "k256"
version = "0.10.4"
@@ -2646,8 +2593,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d"
dependencies = [
"cfg-if 1.0.0",
"ecdsa 0.13.4",
"elliptic-curve 0.11.12",
"ecdsa",
"elliptic-curve",
"sec1",
"sha2",
"sha3",
@@ -2865,7 +2812,7 @@ dependencies = [
"log",
"nymsphinx",
"tokio",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
]
[[package]]
@@ -2905,8 +2852,9 @@ dependencies = [
"nymsphinx-types",
"rand 0.8.5",
"serde",
"task",
"tokio",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
"url",
"validator-client",
"version-checker",
@@ -2938,6 +2886,18 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "multisig-contract-common"
version = "0.1.0"
dependencies = [
"cosmwasm-std",
"cw-utils",
"cw3",
"cw4",
"schemars",
"serde",
]
[[package]]
name = "native-tls"
version = "0.2.10"
@@ -2984,7 +2944,7 @@ version = "0.1.0"
dependencies = [
"tokio",
"tokio-stream",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
]
[[package]]
@@ -3119,7 +3079,7 @@ dependencies = [
"tokio",
"tokio-stream",
"tokio-tungstenite",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
"url",
"validator-client",
"vergen",
@@ -3155,8 +3115,9 @@ dependencies = [
"rocket",
"serde",
"serial_test",
"task",
"tokio",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
"toml",
"topology",
"url",
@@ -3169,7 +3130,6 @@ dependencies = [
name = "nym-network-requester"
version = "1.0.1"
dependencies = [
"bincode",
"clap 2.34.0",
"dirs",
"futures",
@@ -3182,16 +3142,33 @@ dependencies = [
"proxy-helpers",
"publicsuffix",
"rand 0.7.3",
"rocket",
"reqwest",
"serde",
"socks5-requests",
"sqlx",
"statistics",
"thiserror",
"tokio",
"tokio-tungstenite",
"websocket-requests",
]
[[package]]
name = "nym-network-statistics"
version = "0.1.0"
dependencies = [
"dirs",
"log",
"pretty_env_logger",
"rocket",
"serde",
"sqlx",
"statistics",
"thiserror",
"tokio",
"tokio-tungstenite",
]
[[package]]
name = "nym-socks5-client"
version = "1.0.1"
@@ -3228,6 +3205,32 @@ dependencies = [
"version-checker",
]
[[package]]
name = "nym-types"
version = "1.0.0"
dependencies = [
"coconut-interface",
"config",
"cosmrs",
"cosmwasm-std",
"eyre",
"itertools",
"log",
"mixnet-contract-common",
"reqwest",
"schemars",
"serde",
"serde_json",
"strum",
"tempfile",
"thiserror",
"ts-rs",
"url",
"validator-client",
"vesting-contract",
"vesting-contract-common",
]
[[package]]
name = "nym-validator-api"
version = "1.0.1"
@@ -3241,6 +3244,7 @@ dependencies = [
"coconut-interface",
"config",
"console-subscriber",
"cosmwasm-std",
"credential-storage",
"credentials",
"crypto",
@@ -3252,6 +3256,7 @@ dependencies = [
"humantime-serde",
"log",
"mixnet-contract-common",
"multisig-contract-common",
"nymcoconut",
"nymsphinx",
"okapi",
@@ -3273,6 +3278,7 @@ dependencies = [
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-api-requests",
"validator-client",
@@ -3280,6 +3286,24 @@ dependencies = [
"version-checker",
]
[[package]]
name = "nym-wallet-types"
version = "1.0.0"
dependencies = [
"config",
"cosmrs",
"cosmwasm-std",
"mixnet-contract-common",
"nym-types",
"serde",
"serde_json",
"strum",
"ts-rs",
"validator-client",
"vesting-contract",
"vesting-contract-common",
]
[[package]]
name = "nymcoconut"
version = "0.5.0"
@@ -3401,7 +3425,7 @@ dependencies = [
"bytes",
"nymsphinx-params",
"nymsphinx-types",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
]
[[package]]
@@ -3783,24 +3807,14 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447"
dependencies = [
"der 0.4.5",
"spki 0.4.1",
]
[[package]]
name = "pkcs8"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0"
dependencies = [
"der 0.5.1",
"spki 0.5.4",
"der",
"spki",
"zeroize",
]
@@ -3936,7 +3950,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001"
dependencies = [
"bytes",
"prost-derive",
"prost-derive 0.9.0",
]
[[package]]
name = "prost"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc03e116981ff7d8da8e5c220e374587b98d294af7ba7dd7fda761158f00086f"
dependencies = [
"bytes",
"prost-derive 0.10.1",
]
[[package]]
@@ -3952,8 +3976,8 @@ dependencies = [
"log",
"multimap",
"petgraph",
"prost",
"prost-types",
"prost 0.9.0",
"prost-types 0.9.0",
"regex",
"tempfile",
"which",
@@ -3972,6 +3996,19 @@ dependencies = [
"syn",
]
[[package]]
name = "prost-derive"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "prost-types"
version = "0.9.0"
@@ -3979,7 +4016,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a"
dependencies = [
"bytes",
"prost",
"prost 0.9.0",
]
[[package]]
name = "prost-types"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68"
dependencies = [
"bytes",
"prost 0.10.3",
]
[[package]]
@@ -3993,7 +4040,7 @@ dependencies = [
"socks5-requests",
"tokio",
"tokio-test",
"tokio-util 0.6.9",
"tokio-util 0.7.3",
]
[[package]]
@@ -4392,7 +4439,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525"
dependencies = [
"crypto-bigint 0.3.2",
"crypto-bigint",
"hmac 0.11.0",
"zeroize",
]
@@ -4725,9 +4772,9 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
dependencies = [
"der 0.5.1",
"der",
"generic-array 0.14.5",
"pkcs8 0.8.0",
"pkcs8",
"subtle 2.4.1",
"zeroize",
]
@@ -4829,9 +4876,9 @@ dependencies = [
[[package]]
name = "serde-json-wasm"
version = "0.3.2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853"
checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5"
dependencies = [
"serde",
]
@@ -5178,15 +5225,6 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32"
dependencies = [
"der 0.4.5",
]
[[package]]
name = "spki"
version = "0.5.4"
@@ -5194,7 +5232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27"
dependencies = [
"base64ct",
"der 0.5.1",
"der",
]
[[package]]
@@ -5326,6 +5364,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "statistics"
version = "1.0.1"
dependencies = [
"reqwest",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "stdweb"
version = "0.4.20"
@@ -5397,6 +5445,28 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
dependencies = [
"heck 0.3.3",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "subtle"
version = "1.0.0"
@@ -5447,6 +5517,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "task"
version = "0.1.0"
dependencies = [
"log",
"tokio",
"tokio-util 0.7.3",
]
[[package]]
name = "tempfile"
version = "3.3.0"
@@ -5463,9 +5542,9 @@ dependencies = [
[[package]]
name = "tendermint"
version = "0.23.3"
version = "0.23.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9ef686b8ecd36550d0581f0989c9d8607090b23005df479d8e6ba348b5800b9"
checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949"
dependencies = [
"async-trait",
"bytes",
@@ -5473,11 +5552,11 @@ dependencies = [
"ed25519-dalek",
"flex-error",
"futures",
"k256 0.10.4",
"k256",
"num-traits",
"once_cell",
"prost",
"prost-types",
"prost 0.10.3",
"prost-types 0.10.1",
"ripemd160",
"serde",
"serde_bytes",
@@ -5494,9 +5573,9 @@ dependencies = [
[[package]]
name = "tendermint-config"
version = "0.23.3"
version = "0.23.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc127f82e7a8c7337c1f293d65a821380d3407c4c44bc979ef4da0ebc3b31ed"
checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd"
dependencies = [
"flex-error",
"serde",
@@ -5508,16 +5587,16 @@ dependencies = [
[[package]]
name = "tendermint-proto"
version = "0.23.3"
version = "0.23.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e0a0251fd81bed7420bea0f4d91c2a58f6c9fa34d5b2f70bed0ba8890de5aa"
checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874"
dependencies = [
"bytes",
"flex-error",
"num-derive",
"num-traits",
"prost",
"prost-types",
"prost 0.10.3",
"prost-types 0.10.1",
"serde",
"serde_bytes",
"subtle-encoding",
@@ -5526,9 +5605,9 @@ dependencies = [
[[package]]
name = "tendermint-rpc"
version = "0.23.3"
version = "0.23.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "626c493e9ced3a9de37583bbd929f4b6dbd49aa513ab9b4776aa44a9332ce9b5"
checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6"
dependencies = [
"async-trait",
"bytes",
@@ -5699,9 +5778,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.17.0"
version = "1.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
checksum = "95eec79ea28c00a365f539f1961e9278fbcaf81c0ff6aaf0e93c181352446948"
dependencies = [
"bytes",
"libc",
@@ -5762,9 +5841,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
version = "0.1.8"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -5809,20 +5888,20 @@ dependencies = [
"futures-sink",
"log",
"pin-project-lite",
"slab",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"slab",
"tokio",
"tracing",
]
@@ -5855,8 +5934,8 @@ dependencies = [
"hyper-timeout",
"percent-encoding",
"pin-project",
"prost",
"prost-derive",
"prost 0.9.0",
"prost-derive 0.9.0",
"tokio",
"tokio-stream",
"tokio-util 0.6.9",
@@ -5907,7 +5986,7 @@ dependencies = [
"rand 0.8.5",
"slab",
"tokio",
"tokio-util 0.7.1",
"tokio-util 0.7.3",
"tower-layer",
"tower-service",
"tracing",
@@ -6014,6 +6093,21 @@ dependencies = [
"ts-rs-macros",
]
[[package]]
name = "ts-rs-cli"
version = "0.1.0"
dependencies = [
"anyhow",
"mixnet-contract-common",
"nym-types",
"nym-wallet-types",
"ts-rs",
"validator-api-requests",
"validator-client",
"vesting-contract-common",
"walkdir",
]
[[package]]
name = "ts-rs-macros"
version = "6.1.2"
@@ -6196,18 +6290,22 @@ dependencies = [
"async-trait",
"base64",
"bip39",
"coconut-bandwidth-contract-common",
"coconut-interface",
"colored",
"config",
"cosmrs 0.4.1 (git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation)",
"cosmrs",
"cosmwasm-std",
"cw3",
"execute",
"flate2",
"futures",
"itertools",
"log",
"mixnet-contract-common",
"multisig-contract-common",
"network-defaults",
"prost",
"prost 0.10.3",
"reqwest",
"serde",
"serde_json",
@@ -6627,6 +6725,7 @@ checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f"
dependencies = [
"curve25519-dalek",
"rand_core 0.5.1",
"serde",
"zeroize",
]
+8 -1
View File
@@ -31,10 +31,12 @@ members = [
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/bandwidth-claim-contract",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/mixnode-common",
"common/network-defaults",
@@ -51,17 +53,22 @@ members = [
"common/nymsphinx/params",
"common/nymsphinx/types",
"common/pemstore",
"common/statistics",
"common/socks5/proxy-helpers",
"common/socks5/requests",
"common/task",
"common/topology",
"common/types",
"common/wasm-utils",
"explorer-api",
"gateway",
"gateway/gateway-requests",
"mixnode",
"service-providers/network-requester",
"service-providers/network-statistics",
"validator-api",
"validator-api/validator-api-requests",
"tools/ts-rs-cli"
]
default-members = [
@@ -74,4 +81,4 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly"]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly", "nym-wallet"]
+24 -5
View File
@@ -1,11 +1,11 @@
test: build clippy-all cargo-test wasm fmt
no-clippy: build cargo-test wasm fmt
happy: fmt clippy-happy test
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet
cargo-test: test-main test-contracts test-wallet
build: build-contracts build-wallet build-main
fmt: fmt-main fmt-contracts fmt-wallet
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet clippy-all-connect
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect
cargo-test: test-main test-contracts test-wallet test-connect
build: build-contracts build-wallet build-main build-connect
fmt: fmt-main fmt-contracts fmt-wallet fmt-connect
clippy-happy-main:
cargo clippy
@@ -16,6 +16,9 @@ clippy-happy-contracts:
clippy-happy-wallet:
cargo clippy --manifest-path nym-wallet/Cargo.toml
clippy-happy-connect:
cargo clippy --manifest-path nym-connect/Cargo.toml
clippy-all-main:
cargo clippy --workspace --all-features -- -D warnings
@@ -25,6 +28,9 @@ clippy-all-contracts:
clippy-all-wallet:
cargo clippy --workspace --manifest-path nym-wallet/Cargo.toml --all-features -- -D warnings
clippy-all-connect:
cargo clippy --workspace --manifest-path nym-connect/Cargo.toml --all-features -- -D warnings
test-main:
cargo test --all-features --workspace
@@ -34,6 +40,9 @@ test-contracts:
test-wallet:
cargo test --manifest-path nym-wallet/Cargo.toml --all-features
test-connect:
cargo test --manifest-path nym-connect/Cargo.toml --all-features
build-main:
cargo build --workspace
@@ -43,6 +52,9 @@ build-contracts:
build-wallet:
cargo build --manifest-path nym-wallet/Cargo.toml --workspace
build-connect:
cargo build --manifest-path nym-connect/Cargo.toml --workspace
fmt-main:
cargo fmt --all
@@ -52,5 +64,12 @@ fmt-contracts:
fmt-wallet:
cargo fmt --manifest-path nym-wallet/Cargo.toml --all
fmt-connect:
cargo fmt --manifest-path nym-connect/Cargo.toml --all
wasm:
RUSTFLAGS='-C link-arg=-s' cargo build --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown
generate-typescript:
cd tools/ts-rs-cli && cargo run && cd ../..
yarn types:lint:fix
+8
View File
@@ -0,0 +1,8 @@
Update fonts by doing the following:
1. Go to https://fonts.google.com/specimen/Open+Sans
2. Add all the styles you want and select `@import`
3. Copy the url (e.g. curl https://fonts.googleapis.com/css2\?family\=Open+Sans:ital,wght@0,300\;0,400\;0,500\;0,600\;0,700\;0,800\;1,300\;1,400\;1,500\;1,600\;1,700\;1,800\&display\=swap)
4. Run `curl curl https://fonts.googleapis.com/css2\?family\=Open+Sans:ital,wght@0,300\;0,400\;0,500\;0,600\;0,700\;0,800\;1,300\;1,400\;1,500\;1,600\;1,700\;1,800\&display\=swap`
5. Use the response as the CSS import directives and download the font files for each font weight
6. Remember to delete any old font files
+96
View File
@@ -0,0 +1,96 @@
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 500;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk_RkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 600;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkyFjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 800;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk0ZjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 500;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjr0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1y4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsg-1y4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 800;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgshZ1y4n.ttf) format('truetype');
}
+7
View File
@@ -0,0 +1,7 @@
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M171.7,30.3001 C132.7,-8.7999 69.3001,-8.7999 30.3001,30.3001 C-8.7999,69.4001 -8.7999,132.7 30.3001,171.7 C69.4001,210.8 132.7,210.8 171.7,171.7 C210.8,132.7 210.8,69.3001 171.7,30.3001 Z M163.1,163.1 C128.8,197.4 73.1001,197.4 38.8001,163.1 C4.5001,128.8 4.5001,73.1001 38.8001,38.8001 C73.1001,4.5001 128.8,4.5001 163.1,38.8001 C197.5,73.2001 197.5,128.8 163.1,163.1 Z" id="Shape" fill="#fff"></path>
<path d="M163.1,38.9 C128.8,4.60005 73.1002,4.60005 38.8002,38.9 C4.50019,73.2 4.50019,128.9 38.8002,163.2 C73.1002,197.5 128.8,197.5 163.1,163.2 C197.5,128.8 197.5,73.2 163.1,38.9 Z" id="Shape" fill="#000"></path>
<g id="T" transform="translate(25, 25) scale(5,5)">
<path d="M18.4804688,24 C19.203125,24 19.7182617,23.8608398 20.0258789,23.5825195 C20.3334961,23.3041992 20.4873047,22.9453125 20.4873047,22.5058594 C20.4873047,22.0566406 20.3334961,21.6928711 20.0258789,21.4145508 C19.7182617,21.1362305 19.203125,20.9970703 18.4804688,20.9970703 L18.4804688,20.9970703 L16.4589844,20.9970703 L16.4589844,9.24902344 L19.7548828,9.24902344 L19.7548828,12.0908203 C19.7548828,12.8134766 19.894043,13.3286133 20.1723633,13.6362305 C20.4506836,13.9438477 20.8095703,14.0976562 21.2490234,14.0976562 C21.6982422,14.0976562 22.0620117,13.9438477 22.340332,13.6362305 C22.6186523,13.3286133 22.7578125,12.8134766 22.7578125,12.0908203 L22.7578125,12.0908203 L22.7578125,6.24609375 L7.20117188,6.23144531 L7.20117188,12.0908203 C7.20117188,12.8134766 7.34033203,13.3286133 7.61865234,13.6362305 C7.89697266,13.9438477 8.25585938,14.0976562 8.6953125,14.0976562 C9.14453125,14.0976562 9.50830078,13.9438477 9.78662109,13.6362305 C10.0649414,13.3286133 10.2041016,12.8134766 10.2041016,12.0908203 L10.2041016,12.0908203 L10.2041016,9.24902344 L13.4560547,9.24902344 L13.4560547,20.9970703 L11.4492188,20.9970703 C10.7265625,20.9970703 10.2114258,21.1362305 9.90380859,21.4145508 C9.59619141,21.6928711 9.44238281,22.0517578 9.44238281,22.4912109 C9.44238281,22.9404297 9.59619141,23.3041992 9.90380859,23.5825195 C10.2114258,23.8608398 10.7265625,24 11.4492188,24 L11.4492188,24 L18.4804688,24 Z" id="T" fill="#fff"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

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

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

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

After

Width:  |  Height:  |  Size: 2.2 KiB

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

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+1 -1
View File
@@ -14,7 +14,7 @@ log = "0.4"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { version = "1.0", features = ["derive"] }
sled = "0.34"
tokio = { version = "1.4", features = ["macros"] }
tokio = { version = "1.19.1", features = ["macros"] }
url = { version ="2.2", features = ["serde"] }
# internal
@@ -6,7 +6,7 @@ use crate::client::real_messages_control::acknowledgement_control::Retransmissio
use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
use futures::StreamExt;
use log::*;
use nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue, QueueKey, TimerError};
use nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue, QueueKey};
use nymsphinx::chunking::fragment::FragmentIdentifier;
use nymsphinx::Delay as SphinxDelay;
use std::collections::HashMap;
@@ -209,16 +209,11 @@ impl ActionController {
}
// note: when the entry expires it's automatically removed from pending_acks_timers
fn handle_expired_ack_timer(
&mut self,
expired_ack: Result<Expired<FragmentIdentifier>, TimerError>,
) {
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
.expect("Tokio timer returned an error!")
.into_inner();
let frag_id = expired_ack.into_inner();
trace!("{} has expired", frag_id);
+1 -1
View File
@@ -345,7 +345,7 @@ pub struct Client<T> {
nym_root_directory: PathBuf,
#[serde(skip)]
super_struct: PhantomData<*const T>,
super_struct: PhantomData<T>,
}
impl<T: NymConfig> Default for Client<T> {
+1 -2
View File
@@ -15,9 +15,8 @@ rand = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
url = "2.2"
tokio = { version = "1.4", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime
tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime
coconut-bandwidth-contract-common = { path = "../../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
coconut-interface = { path = "../../common/coconut-interface" }
credentials = { path = "../../common/credentials" }
credential-storage = { path = "../../common/credential-storage" }
File diff suppressed because one or more lines are too long
+17 -35
View File
@@ -2,66 +2,48 @@
// SPDX-License-Identifier: Apache-2.0
use bip39::Mnemonic;
use coconut_bandwidth_contract_common::deposit::DepositData;
use std::str::FromStr;
use url::Url;
use crate::error::Result;
use crate::{CONTRACT_ADDRESS, MNEMONIC, NYMD_URL};
use crate::{MNEMONIC, NYMD_URL};
use coconut_bandwidth_contract_common::msg::ExecuteMsg;
use network_defaults::DEFAULT_NETWORK;
use validator_client::nymd::{
AccountId, CosmosCoin, Decimal, Denom, NymdClient, SigningNymdClient,
};
use network_defaults::{DEFAULT_NETWORK, DENOM, VOUCHER_INFO};
use validator_client::nymd::traits::CoconutBandwidthSigningClient;
use validator_client::nymd::{Coin, Fee, NymdClient, SigningNymdClient};
pub(crate) struct Client {
nymd_client: NymdClient<SigningNymdClient>,
denom: Denom,
contract_address: AccountId,
}
impl Client {
pub fn new() -> Self {
let nymd_url = Url::from_str(NYMD_URL).unwrap();
let mnemonic = Mnemonic::from_str(MNEMONIC).unwrap();
let nymd_client = NymdClient::connect_with_mnemonic(
DEFAULT_NETWORK,
nymd_url.as_ref(),
None,
None,
None,
mnemonic,
None,
)
.unwrap();
let denom = Denom::from_str(network_defaults::DENOM).unwrap();
let contract_address = AccountId::from_str(CONTRACT_ADDRESS).unwrap();
let nymd_client =
NymdClient::connect_with_mnemonic(DEFAULT_NETWORK, nymd_url.as_ref(), mnemonic, None)
.unwrap();
Client {
nymd_client,
denom,
contract_address,
}
Client { nymd_client }
}
pub async fn deposit(
&self,
amount: u64,
info: &str,
verification_key: String,
encryption_key: String,
fee: Option<Fee>,
) -> Result<String> {
let req = ExecuteMsg::DepositFunds {
data: DepositData::new(info.to_string(), verification_key, encryption_key),
};
let funds = vec![CosmosCoin {
denom: self.denom.clone(),
amount: Decimal::from(amount),
}];
let amount = Coin::new(amount as u128, DENOM.to_string());
Ok(self
.nymd_client
.execute(&self.contract_address, &req, Default::default(), "", funds)
.deposit(
amount,
String::from(VOUCHER_INFO),
verification_key,
encryption_key,
fee,
)
.await?
.transaction_hash
.to_string())
+1 -1
View File
@@ -55,9 +55,9 @@ impl Execute for Deposit {
let tx_hash = client
.deposit(
self.amount,
VOUCHER_INFO,
signing_keypair.public_key.clone(),
encryption_keypair.public_key.clone(),
None,
)
.await?;
-2402
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -27,7 +27,7 @@ pretty_env_logger = "0.4" # for formatting log messages
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
serde = { version = "1.0.104", features = ["derive"] } # for config serialization/deserialization
sled = "0.34" # for storage of replySURB decryption keys
tokio = { version = "1.4", features = ["rt-multi-thread", "net", "signal"] } # async runtime
tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal"] } # async runtime
tokio-tungstenite = "0.14" # websocket
## internal
+14 -2
View File
@@ -119,6 +119,7 @@ async fn gateway_details(
.expect("The list of validator apis is empty");
let validator_client = validator_client::ApiClient::new(validator_api.clone());
log::trace!("Fetching list of gateways from: {}", validator_api);
let gateways = validator_client.get_cached_gateways().await.unwrap();
let valid_gateways = gateways
.into_iter()
@@ -186,6 +187,9 @@ pub async fn execute(matches: ArgMatches<'static>) {
let id = matches.value_of("id").unwrap(); // required for now
let already_init = if Config::default_config_file_path(Some(id)).exists() {
if matches.is_present("gateway") {
panic!("At the moment, gateway information can't be overwritten. If you want to point to a different gateway, client {}'s directory will need to be manually removed", id);
}
println!("Client \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id);
true
} else {
@@ -210,12 +214,14 @@ pub async fn execute(matches: ArgMatches<'static>) {
let mut key_manager = KeyManager::new(&mut rng);
let chosen_gateway_id = matches.value_of("gateway");
log::trace!("Chosen gateway: {:?}", chosen_gateway_id);
let gateway_details = gateway_details(
config.get_base().get_validator_api_endpoints(),
chosen_gateway_id,
)
.await;
log::trace!("Used gateway: {}", gateway_details);
let shared_keys =
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await;
@@ -238,8 +244,14 @@ pub async fn execute(matches: ArgMatches<'static>) {
.save_to_file(None)
.expect("Failed to save the config file");
println!("Saved configuration file to {:?}", config_save_location);
println!("Using gateway: {}", config.get_base().get_gateway_id(),);
println!("Client configuration completed.\n\n\n");
println!("Using gateway: {}", config.get_base().get_gateway_id());
log::debug!("Gateway id: {}", config.get_base().get_gateway_id());
log::debug!("Gateway owner: {}", config.get_base().get_gateway_owner());
log::debug!(
"Gateway listener: {}",
config.get_base().get_gateway_listener()
);
println!("Client configuration completed.");
show_address(&config);
}
+1 -5
View File
@@ -39,15 +39,11 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
.set_custom_validator_apis(parse_validators(raw_validators));
}
if let Some(gateway_id) = matches.value_of("gateway") {
config.get_base_mut().with_gateway_id(gateway_id);
}
if matches.is_present("disable-socket") {
config = config.with_socket(SocketType::None);
}
if let Some(port) = matches.value_of("port").map(|port| port.parse::<u16>()) {
if let Some(port) = matches.value_of("port").map(str::parse) {
if let Err(err) = port {
// if port was overridden, it must be parsable
panic!("Invalid port value provided - {:?}", err);
+3 -3
View File
@@ -70,7 +70,9 @@ pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
fn version_check(cfg: &Config) -> bool {
let binary_version = env!("CARGO_PKG_VERSION");
let config_version = cfg.get_base().get_version();
if binary_version != config_version {
if binary_version == config_version {
true
} else {
warn!("The mixnode binary has different version than what is specified in config file! {} and {}", binary_version, config_version);
if is_minor_version_compatible(binary_version, config_version) {
info!("but they are still semver compatible. However, consider running the `upgrade` command");
@@ -79,8 +81,6 @@ fn version_check(cfg: &Config) -> bool {
error!("and they are semver incompatible! - please run the `upgrade` command before attempting `run` again");
false
}
} else {
true
}
}
+7 -7
View File
@@ -131,22 +131,22 @@ fn minor_0_12_upgrade(
config
}
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Version) {
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: &Version) {
loop {
let config_version = parse_config_version(&config);
if config_version == package_version {
if &config_version == package_version {
println!("You're using the most recent version!");
return;
}
config = match config_version.major {
0 => match config_version.minor {
9 | 10 => outdated_upgrade(&config_version, &package_version),
11 => minor_0_12_upgrade(config, matches, &config_version, &package_version),
_ => unsupported_upgrade(&config_version, &package_version),
9 | 10 => outdated_upgrade(&config_version, package_version),
11 => minor_0_12_upgrade(config, matches, &config_version, package_version),
_ => unsupported_upgrade(&config_version, package_version),
},
_ => unsupported_upgrade(&config_version, &package_version),
_ => unsupported_upgrade(&config_version, package_version),
}
}
}
@@ -167,5 +167,5 @@ pub fn execute(matches: &ArgMatches<'_>) {
}
// here be upgrade path to 0.9.X and beyond based on version number from config
do_upgrade(existing_config, matches, package_version)
do_upgrade(existing_config, matches, &package_version)
}
+2
View File
@@ -108,5 +108,7 @@ fn setup_logging() {
.filter_module("want", log::LevelFilter::Warn)
.filter_module("tungstenite", log::LevelFilter::Warn)
.filter_module("tokio_tungstenite", log::LevelFilter::Warn)
.filter_module("handlebars", log::LevelFilter::Warn)
.filter_module("sled", log::LevelFilter::Warn)
.init();
}
+1 -1
View File
@@ -20,7 +20,7 @@ pretty_env_logger = "0.4"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { version = "1.0", features = ["derive"] } # for config serialization/deserialization
snafu = "0.6"
tokio = { version = "1.4", features = ["rt-multi-thread", "net", "signal"] }
tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal"] }
url = "2.2"
# internal
+26 -1
View File
@@ -20,6 +20,7 @@ use client_core::client::topology_control::{
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use crypto::asymmetric::identity;
use futures::channel::mpsc;
use futures::StreamExt;
use gateway_client::bandwidth::BandwidthController;
use gateway_client::{
AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver,
@@ -35,7 +36,17 @@ use crate::socks::{
server::SphinxSocksServer,
};
pub(crate) mod config;
pub mod config;
// Channels used to control the main task from outside
pub type Socks5ControlMessageSender = mpsc::UnboundedSender<Socks5ControlMessage>;
pub type Socks5ControlMessageReceiver = mpsc::UnboundedReceiver<Socks5ControlMessage>;
#[derive(Debug)]
pub enum Socks5ControlMessage {
/// Tell the main task to stop
Stop,
}
pub struct NymClient {
/// Client configuration options, including, among other things, packet sending rates,
@@ -272,6 +283,20 @@ impl NymClient {
);
}
// Variant of `run_forever` that listends for remote control messages
pub async fn run_and_listen(&mut self, mut receiver: Socks5ControlMessageReceiver) {
self.start().await;
tokio::select! {
message = receiver.next() => match message {
Some(Socks5ControlMessage::Stop) => {
log::info!("Received: {:?}", message);
log::info!("Shutting down");
}
None => log::info!("none"),
}
}
}
pub async fn start(&mut self) {
info!("Starting nym client");
// channels for inter-component communication
+9 -3
View File
@@ -88,7 +88,8 @@ pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
app
}
async fn register_with_gateway(
// TODO: make this private again after refactoring the config setup
pub async fn register_with_gateway(
gateway: &gateway::Node,
our_identity: Arc<identity::KeyPair>,
) -> Arc<SharedKeys> {
@@ -110,7 +111,8 @@ async fn register_with_gateway(
.expect("failed to register with the gateway!")
}
async fn gateway_details(
// TODO: make this private again after refactoring the config setup
pub async fn gateway_details(
validator_servers: Vec<Url>,
chosen_gateway_id: Option<&str>,
) -> gateway::Node {
@@ -144,7 +146,8 @@ async fn gateway_details(
}
}
fn show_address(config: &Config) {
// TODO: make this private again after refactoring the config setup
pub fn show_address(config: &Config) {
fn load_identity_keys(pathfinder: &ClientKeyPathfinder) -> identity::KeyPair {
let identity_keypair: identity::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
@@ -187,6 +190,9 @@ pub async fn execute(matches: ArgMatches<'static>) {
let provider_address = matches.value_of("provider").unwrap();
let already_init = if Config::default_config_file_path(Some(id)).exists() {
if matches.is_present("gateway") {
panic!("At the moment, gateway information can't be overwritten. If you want to point to a different gateway, client {}'s directory will need to be manually removed", id);
}
println!("Socks5 client \"{}\" was already initialised before! Config information will be overwritten (but keys will be kept)!", id);
true
} else {
+1 -5
View File
@@ -5,7 +5,7 @@ use crate::client::config::Config;
use clap::ArgMatches;
use url::Url;
pub(crate) mod init;
pub mod init;
pub(crate) mod run;
pub(crate) mod upgrade;
@@ -39,10 +39,6 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
.set_custom_validator_apis(parse_validators(raw_validators));
}
if let Some(gateway_id) = matches.value_of("gateway") {
config.get_base_mut().with_gateway_id(gateway_id);
}
if let Some(port) = matches.value_of("port").map(|port| port.parse::<u16>()) {
if let Err(err) = port {
// if port was overridden, it must be parsable
+5
View File
@@ -2,4 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
pub mod client;
// This is only used as we reach into the init functions in nym-connect. We need to refactor the
// init functions so that nym-connect can just call the same init function as the regular socks5
// client.
#[allow(unused)]
pub mod commands;
pub mod socks;
+1 -1
View File
@@ -35,7 +35,7 @@ default-features = false
# non-wasm-only dependencies
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
version = "1.4"
version = "1.19.1"
features = ["macros", "rt", "net", "sync", "time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
@@ -101,7 +101,7 @@ impl GatewayClient {
}
pub fn set_disabled_credentials_mode(&mut self, disabled_credentials_mode: bool) {
self.disabled_credentials_mode = disabled_credentials_mode
self.disabled_credentials_mode = disabled_credentials_mode;
}
// TODO: later convert into proper builder methods
@@ -496,7 +496,6 @@ impl GatewayClient {
self.shared_key.as_ref().unwrap(),
iv,
)
.ok_or(GatewayClientError::SerializeCredential)?
.into();
self.bandwidth_remaining = match self.send_websocket_message(msg).await? {
ServerResponse::Bandwidth { available_total } => Ok(available_total),
+2 -2
View File
@@ -9,8 +9,8 @@ edition = "2021"
[dependencies]
futures = "0.3"
log = "0.4.8"
tokio = { version = "1.4", features = ["time", "net", "rt"] }
tokio-util = { version = "0.6", features = ["codec"] }
tokio = { version = "1.19.1", features = ["time", "net", "rt"] }
tokio-util = { version = "0.7.3", features = ["codec"] }
# internal
nymsphinx = {path = "../../nymsphinx" }
+10 -4
View File
@@ -10,8 +10,11 @@ rust-version = "1.56"
[dependencies]
base64 = "0.13"
colored = "2.0"
cw3 = "0.13.1"
mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
coconut-bandwidth-contract-common = { path= "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
vesting-contract = { path = "../../../contracts/vesting" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
@@ -19,7 +22,7 @@ reqwest = { version = "0.11", features = ["json"] }
thiserror = "1"
log = "0.4"
url = { version = "2.2", features = ["serde"] }
tokio = { version = "1.10", features = ["sync", "time"] }
tokio = { version = "1.19.1", features = ["sync", "time"] }
futures = "0.3"
coconut-interface = { path = "../../coconut-interface" }
@@ -32,12 +35,13 @@ validator-api-requests = { path = "../../../validator-api/validator-api-requests
async-trait = { version = "0.1.51", optional = true }
bip39 = { version = "1", features = ["rand"], optional = true }
config = { path = "../../config", optional = true }
cosmrs = { git = "https://github.com/nymtech/cosmos-rust", branch = "bugfix/account-id-length-validation", features = ["rpc", "bip32", "cosmwasm"], optional = true}
prost = { version = "0.9", default-features = false, optional = true }
cosmrs = { version = "0.7.0", features = ["rpc", "bip32", "cosmwasm"], optional = true}
prost = { version = "0.10", default-features = false, optional = true }
flate2 = { version = "1.0.20", optional = true }
sha2 = { version = "0.9.5", optional = true }
itertools = { version = "0.10", optional = true }
cosmwasm-std = { version = "1.0.0-beta8", optional = true }
cosmwasm-std = { version = "1.0.0", optional = true }
execute = { path = "../../execute" }
[dev-dependencies]
ts-rs = "6.1.2"
@@ -54,3 +58,5 @@ nymd-client = [
"itertools",
"cosmwasm-std",
]
generate-ts = []
+108 -60
View File
@@ -2,16 +2,20 @@
// SPDX-License-Identifier: Apache-2.0
use crate::{validator_api, ValidatorClientError};
use coconut_interface::{BlindSignRequestBody, BlindedSignatureResponse, VerificationKeyResponse};
use coconut_interface::{
BlindSignRequestBody, BlindedSignatureResponse, ExecuteReleaseFundsRequestBody,
ProposeReleaseFundsRequestBody, ProposeReleaseFundsResponse, VerificationKeyResponse,
VerifyCredentialBody, VerifyCredentialResponse,
};
use mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixNodeBond};
use url::Url;
#[cfg(feature = "nymd-client")]
use validator_api_requests::models::UptimeResponse;
use validator_api_requests::models::{
CoreNodeStatusResponse, MixnodeStatusResponse, RewardEstimationResponse,
StakeSaturationResponse,
};
#[cfg(feature = "nymd-client")]
use validator_api_requests::models::{MixNodeBondAnnotated, UptimeResponse};
#[cfg(feature = "nymd-client")]
use network_defaults::DEFAULT_NETWORK;
@@ -29,8 +33,6 @@ use mixnet_contract_common::{
};
#[cfg(feature = "nymd-client")]
use std::collections::{HashMap, HashSet};
#[cfg(feature = "nymd-client")]
use std::str::FromStr;
#[cfg(feature = "nymd-client")]
#[must_use]
@@ -39,9 +41,9 @@ pub struct Config {
network: network_defaults::all::Network,
api_url: Url,
nymd_url: Url,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
mixnet_contract_address: cosmrs::AccountId,
vesting_contract_address: cosmrs::AccountId,
bandwidth_claim_contract_address: cosmrs::AccountId,
mixnode_page_limit: Option<u32>,
gateway_page_limit: Option<u32>,
@@ -51,20 +53,22 @@ pub struct Config {
#[cfg(feature = "nymd-client")]
impl Config {
pub fn new(
network: network_defaults::all::Network,
nymd_url: Url,
api_url: Url,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
) -> Self {
pub fn new(network: network_defaults::all::Network, nymd_url: Url, api_url: Url) -> Self {
Config {
network,
nymd_url,
mixnet_contract_address,
vesting_contract_address,
erc20_bridge_contract_address,
mixnet_contract_address: DEFAULT_NETWORK
.mixnet_contract_address()
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: DEFAULT_NETWORK
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: DEFAULT_NETWORK
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
api_url,
mixnode_page_limit: None,
gateway_page_limit: None,
@@ -73,6 +77,21 @@ impl Config {
}
}
pub fn with_mixnode_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.mixnet_contract_address = address;
self
}
pub fn with_vesting_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.vesting_contract_address = address;
self
}
pub fn with_bandwidth_claim_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.bandwidth_claim_contract_address = address;
self
}
pub fn with_mixnode_page_limit(mut self, limit: Option<u32>) -> Config {
self.mixnode_page_limit = limit;
self
@@ -97,9 +116,9 @@ impl Config {
#[cfg(feature = "nymd-client")]
pub struct Client<C> {
pub network: network_defaults::all::Network,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
mixnet_contract_address: cosmrs::AccountId,
vesting_contract_address: cosmrs::AccountId,
bandwidth_claim_contract_address: cosmrs::AccountId,
mnemonic: Option<bip39::Mnemonic>,
mixnode_page_limit: Option<u32>,
@@ -122,18 +141,18 @@ impl Client<SigningNymdClient> {
let nymd_client = NymdClient::connect_with_mnemonic(
config.network,
config.nymd_url.as_str(),
config.mixnet_contract_address.clone(),
config.vesting_contract_address.clone(),
config.erc20_bridge_contract_address.clone(),
mnemonic.clone(),
None,
)?;
)?
.with_mixnet_contract_address(config.mixnet_contract_address.clone())
.with_vesting_contract_address(config.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(config.bandwidth_claim_contract_address.clone());
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
erc20_bridge_contract_address: config.erc20_bridge_contract_address,
bandwidth_claim_contract_address: config.bandwidth_claim_contract_address,
mnemonic: Some(mnemonic),
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
@@ -148,12 +167,12 @@ impl Client<SigningNymdClient> {
self.nymd = NymdClient::connect_with_mnemonic(
self.network,
new_endpoint.as_ref(),
self.mixnet_contract_address.clone(),
self.vesting_contract_address.clone(),
self.erc20_bridge_contract_address.clone(),
self.mnemonic.clone().unwrap(),
None,
)?;
)?
.with_mixnet_contract_address(self.mixnet_contract_address.clone())
.with_vesting_contract_address(self.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(self.bandwidth_claim_contract_address.clone());
Ok(())
}
@@ -166,32 +185,15 @@ impl Client<SigningNymdClient> {
impl Client<QueryNymdClient> {
pub fn new_query(config: Config) -> Result<Client<QueryNymdClient>, ValidatorClientError> {
let validator_api_client = validator_api::Client::new(config.api_url.clone());
let nymd_client = NymdClient::connect(
config.nymd_url.as_str(),
Some(config.mixnet_contract_address.clone().unwrap_or_else(|| {
cosmrs::AccountId::from_str(DEFAULT_NETWORK.mixnet_contract_address()).unwrap()
})),
Some(config.vesting_contract_address.clone().unwrap_or_else(|| {
cosmrs::AccountId::from_str(DEFAULT_NETWORK.vesting_contract_address()).unwrap()
})),
Some(
config
.erc20_bridge_contract_address
.clone()
.unwrap_or_else(|| {
cosmrs::AccountId::from_str(
DEFAULT_NETWORK.bandwidth_claim_contract_address(),
)
.unwrap()
}),
),
)?;
let nymd_client = NymdClient::connect(config.nymd_url.as_str())?
.with_mixnet_contract_address(config.mixnet_contract_address.clone())
.with_vesting_contract_address(config.vesting_contract_address.clone());
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
erc20_bridge_contract_address: config.erc20_bridge_contract_address,
bandwidth_claim_contract_address: config.bandwidth_claim_contract_address,
mnemonic: None,
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
@@ -203,12 +205,10 @@ impl Client<QueryNymdClient> {
}
pub fn change_nymd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
self.nymd = NymdClient::connect(
new_endpoint.as_ref(),
self.mixnet_contract_address.clone(),
self.vesting_contract_address.clone(),
self.erc20_bridge_contract_address.clone(),
)?;
self.nymd = NymdClient::connect(new_endpoint.as_ref())?
.with_mixnet_contract_address(self.mixnet_contract_address.clone())
.with_vesting_contract_address(self.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(self.bandwidth_claim_contract_address.clone());
Ok(())
}
}
@@ -222,10 +222,10 @@ impl<C> Client<C> {
// use case: somebody initialised client without a contract in order to upload and initialise one
// and now they want to actually use it without making new client
pub fn set_mixnet_contract_address(&mut self, mixnet_contract_address: cosmrs::AccountId) {
self.mixnet_contract_address = Some(mixnet_contract_address)
self.mixnet_contract_address = mixnet_contract_address
}
pub fn get_mixnet_contract_address(&self) -> Option<cosmrs::AccountId> {
pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId {
self.mixnet_contract_address.clone()
}
@@ -233,18 +233,36 @@ impl<C> Client<C> {
Ok(self.validator_api.get_mixnodes().await?)
}
pub async fn get_cached_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.validator_api.get_mixnodes_detailed().await?)
}
pub async fn get_cached_rewarded_mixnodes(
&self,
) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
Ok(self.validator_api.get_rewarded_mixnodes().await?)
}
pub async fn get_cached_rewarded_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.validator_api.get_rewarded_mixnodes_detailed().await?)
}
pub async fn get_cached_active_mixnodes(
&self,
) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
Ok(self.validator_api.get_active_mixnodes().await?)
}
pub async fn get_cached_active_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorClientError> {
Ok(self.validator_api.get_active_mixnodes_detailed().await?)
}
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
Ok(self.validator_api.get_gateways().await?)
}
@@ -715,4 +733,34 @@ impl ApiClient {
) -> Result<VerificationKeyResponse, ValidatorClientError> {
Ok(self.validator_api.get_coconut_verification_key().await?)
}
pub async fn verify_bandwidth_credential(
&self,
request_body: &VerifyCredentialBody,
) -> Result<VerifyCredentialResponse, ValidatorClientError> {
Ok(self
.validator_api
.verify_bandwidth_credential(request_body)
.await?)
}
pub async fn propose_release_funds(
&self,
request_body: &ProposeReleaseFundsRequestBody,
) -> Result<ProposeReleaseFundsResponse, ValidatorClientError> {
Ok(self
.validator_api
.propose_release_funds(request_body)
.await?)
}
pub async fn execute_release_funds(
&self,
request_body: &ExecuteReleaseFundsRequestBody,
) -> Result<(), ValidatorClientError> {
Ok(self
.validator_api
.execute_release_funds(request_body)
.await?)
}
}
@@ -19,7 +19,7 @@ const CONNECTION_TEST_TIMEOUT_SEC: u64 = 2;
pub async fn run_validator_connection_test<H: BuildHasher + 'static>(
nymd_urls: impl Iterator<Item = (Network, Url)>,
api_urls: impl Iterator<Item = (Network, Url)>,
mixnet_contract_address: HashMap<Network, Option<cosmrs::AccountId>, H>,
mixnet_contract_address: HashMap<Network, cosmrs::AccountId, H>,
) -> (
HashMap<Network, Vec<(Url, bool)>>,
HashMap<Network, Vec<(Url, bool)>>,
@@ -47,14 +47,15 @@ pub async fn run_validator_connection_test<H: BuildHasher + 'static>(
fn setup_connection_tests<H: BuildHasher + 'static>(
nymd_urls: impl Iterator<Item = (Network, Url)>,
api_urls: impl Iterator<Item = (Network, Url)>,
mixnet_contract_address: HashMap<Network, Option<cosmrs::AccountId>, H>,
mixnet_contract_address: HashMap<Network, cosmrs::AccountId, H>,
) -> impl Iterator<Item = ClientForConnectionTest> {
let nymd_connection_test_clients = nymd_urls.filter_map(move |(network, url)| {
let address = mixnet_contract_address
.get(&network)
.expect("No configured contract address")
.clone();
NymdClient::<QueryNymdClient>::connect(url.as_str(), address, None, None)
NymdClient::<QueryNymdClient>::connect(url.as_str())
.map(|client| client.with_mixnet_contract_address(address))
.map(move |client| ClientForConnectionTest::Nymd(network, url, Box::new(client)))
.ok()
});
@@ -0,0 +1,130 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use std::fmt;
pub use cosmrs::Coin as CosmosCoin;
pub use cosmwasm_std::Coin as CosmWasmCoin;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq)]
pub struct MismatchedDenoms;
// the reason the coin is created here as opposed to different place in the codebase is that
// eventually we want to either publish the cosmwasm client separately or commit it to
// some other project, like cosmrs. Either way, in that case we can't really have
// a dependency on an internal type
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)]
pub struct Coin {
pub amount: u128,
pub denom: String,
}
impl Coin {
pub fn new<S: Into<String>>(amount: u128, denom: S) -> Self {
Coin {
amount,
denom: denom.into(),
}
}
pub fn try_add(&self, other: &Self) -> Result<Self, MismatchedDenoms> {
if self.denom != other.denom {
Err(MismatchedDenoms)
} else {
Ok(Coin {
amount: self.amount + other.amount,
denom: self.denom.clone(),
})
}
}
}
impl fmt::Display for Coin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.amount, self.denom)
}
}
impl From<Coin> for CosmosCoin {
fn from(coin: Coin) -> Self {
assert!(
coin.amount <= u64::MAX as u128,
"the coin amount is higher than the maximum supported by cosmrs"
);
CosmosCoin {
denom: coin
.denom
.parse()
.expect("the coin should have had a valid denom!"),
amount: (coin.amount as u64).into(),
}
}
}
impl From<CosmosCoin> for Coin {
fn from(coin: CosmosCoin) -> Self {
Coin {
amount: coin
.amount
.to_string()
.parse()
.expect("somehow failed to parse string representation of u64"),
denom: coin.denom.to_string(),
}
}
}
impl From<Coin> for CosmWasmCoin {
fn from(coin: Coin) -> Self {
CosmWasmCoin::new(coin.amount, coin.denom)
}
}
impl From<CosmWasmCoin> for Coin {
fn from(coin: CosmWasmCoin) -> Self {
Coin {
amount: coin.amount.u128(),
denom: coin.denom,
}
}
}
pub trait CoinConverter {
type Target;
fn convert_coin(&self) -> Self::Target;
}
impl CoinConverter for CosmosCoin {
type Target = CosmWasmCoin;
fn convert_coin(&self) -> Self::Target {
CosmWasmCoin::new(
self.amount
.to_string()
.parse()
.expect("cosmos coin had an invalid amount assigned"),
self.denom.to_string(),
)
}
}
impl CoinConverter for CosmWasmCoin {
type Target = CosmosCoin;
fn convert_coin(&self) -> Self::Target {
assert!(
self.amount.u128() <= u64::MAX as u128,
"the coin amount is higher than the maximum supported by cosmrs"
);
CosmosCoin {
denom: self
.denom
.parse()
.expect("cosmwasm coin had an invalid amount assigned"),
amount: (self.amount.u128() as u64).into(),
}
}
}
@@ -1,6 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::coin::Coin;
use crate::nymd::cosmwasm_client::helpers::{create_pagination, next_page_key};
use crate::nymd::cosmwasm_client::types::{
Account, Code, CodeDetails, Contract, ContractCodeHistoryEntry, ContractCodeId,
@@ -25,8 +26,7 @@ use cosmrs::rpc::{self, HttpClient, Order};
use cosmrs::tendermint::abci::Code as AbciCode;
use cosmrs::tendermint::abci::Transaction;
use cosmrs::tendermint::{abci, block, chain};
use cosmrs::{tx, AccountId, Coin, Denom, Tx};
use cosmwasm_std::Coin as CosmWasmCoin;
use cosmrs::{tx, AccountId, Coin as CosmosCoin, Denom, Tx};
use prost::Message;
use serde::{Deserialize, Serialize};
use std::convert::{TryFrom, TryInto};
@@ -135,7 +135,7 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
res.balance
.map(TryFrom::try_from)
.map(|proto| CosmosCoin::try_from(proto).map(Into::into))
.transpose()
.map_err(|_| NymdError::SerializationError("Coin".to_owned()))
}
@@ -166,16 +166,12 @@ pub trait CosmWasmClient: rpc::Client {
raw_balances
.into_iter()
.map(TryFrom::try_from)
.map(|proto| CosmosCoin::try_from(proto).map(Into::into))
.collect::<Result<_, _>>()
.map_err(|_| NymdError::SerializationError("Coins".to_owned()))
}
// this is annoyingly and inconsistently returning `Vec<CosmWasmCoin>` rather than
// Vec<Coin>, since cosmrs::Coin can't deal with IBC denoms.
// Presumably after https://github.com/cosmos/cosmos-rust/issues/173 is resolved,
// the code could be adjusted
async fn get_total_supply(&self) -> Result<Vec<CosmWasmCoin>, NymdError> {
async fn get_total_supply(&self) -> Result<Vec<Coin>, NymdError> {
let path = Some("/cosmos.bank.v1beta1.Query/TotalSupply".parse().unwrap());
let mut supply = Vec::new();
@@ -198,12 +194,7 @@ pub trait CosmWasmClient: rpc::Client {
supply
.into_iter()
.map(|coin| {
coin.amount.parse().map(|amount| CosmWasmCoin {
denom: coin.denom,
amount,
})
})
.map(|proto| CosmosCoin::try_from(proto).map(Into::into))
.collect::<Result<_, _>>()
.map_err(|_| NymdError::SerializationError("Coins".to_owned()))
}
@@ -483,6 +474,9 @@ pub trait CosmWasmClient: rpc::Client {
// deprecation warning is due to the fact the protobuf files built were based on cosmos-sdk 0.44,
// where they prefer using tx_bytes directly. However, in 0.42, which we are using at the time
// of writing this, the option does not work
// TODO: we should really stop using the `tx` argument here and use `tx_bytes` exlusively,
// however, at the time of writing this update, while our QA and mainnet networks do support it,
// sandbox is still running old version of wasmd that lacks support for `tx_bytes`
#[allow(deprecated)]
async fn query_simulate(
&self,
@@ -68,6 +68,7 @@ pub(crate) fn create_pagination(key: Vec<u8>) -> PageRequest {
offset: 0,
limit: 0,
count_total: false,
reverse: false,
}
}
@@ -4,11 +4,11 @@
use crate::nymd::error::NymdError;
use cosmrs::tendermint::abci;
use itertools::Itertools;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response)
// as theirs logs
#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub struct Log {
#[serde(default)]
// weird thing is that the first msg_index seems to always be undefined on the raw logs
@@ -22,7 +22,7 @@ pub struct Log {
/// Searches in logs for the first event of the given event type and in that event
/// for the first attribute with the given attribute key.
pub(crate) fn find_attribute<'a>(
pub fn find_attribute<'a>(
logs: &'a [Log],
event_type: &str,
attribute_key: &str,
@@ -1,23 +1,6 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryInto;
use std::time::Duration;
use async_trait::async_trait;
use cosmrs::bank::MsgSend;
use cosmrs::distribution::MsgWithdrawDelegatorReward;
use cosmrs::proto::cosmos::tx::signing::v1beta1::SignMode;
use cosmrs::rpc::endpoint::broadcast;
use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl, SimpleRequest};
use cosmrs::staking::{MsgDelegate, MsgUndelegate};
use cosmrs::tx::{self, Msg, SignDoc, SignerInfo};
use cosmrs::{cosmwasm, rpc, AccountId, Any, Coin, Tx};
use log::debug;
use serde::Serialize;
use sha2::Digest;
use sha2::Sha256;
use crate::nymd::cosmwasm_client::client::CosmWasmClient;
use crate::nymd::cosmwasm_client::helpers::{compress_wasm_code, CheckResponse};
use crate::nymd::cosmwasm_client::logs::{self, parse_raw_logs};
@@ -25,20 +8,49 @@ use crate::nymd::cosmwasm_client::types::*;
use crate::nymd::error::NymdError;
use crate::nymd::fee::{Fee, DEFAULT_SIMULATED_GAS_MULTIPLIER};
use crate::nymd::wallet::DirectSecp256k1HdWallet;
use crate::nymd::{CosmosCoin, GasPrice, TxResponse};
// we need to have **a** valid secp256k1 signature for simulation purposes.
// it doesn't matter what it is as long as it parses correctly
const DUMMY_SECP256K1_SIGNATURE: &[u8] = &[
54, 167, 169, 61, 100, 173, 231, 87, 1, 113, 179, 49, 102, 141, 67, 22, 170, 153, 52, 88, 178,
159, 200, 11, 37, 138, 76, 221, 187, 70, 104, 123, 98, 216, 190, 249, 149, 81, 1, 158, 0, 220,
32, 147, 101, 60, 64, 77, 44, 83, 221, 119, 170, 124, 109, 177, 73, 116, 46, 57, 102, 181, 98,
91,
];
use crate::nymd::{Coin, GasPrice, TxResponse};
use async_trait::async_trait;
use cosmrs::bank::MsgSend;
use cosmrs::distribution::MsgWithdrawDelegatorReward;
use cosmrs::proto::cosmos::tx::signing::v1beta1::SignMode;
use cosmrs::rpc::endpoint::broadcast;
use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl, SimpleRequest};
use cosmrs::staking::{MsgDelegate, MsgUndelegate};
use cosmrs::tx::{self, Msg, SignDoc, SignerInfo};
use cosmrs::{cosmwasm, rpc, AccountId, Any, Tx};
use log::debug;
use serde::Serialize;
use sha2::Digest;
use sha2::Sha256;
use std::convert::TryInto;
use std::time::Duration;
const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4);
const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60);
fn empty_fee() -> tx::Fee {
tx::Fee {
amount: vec![],
gas_limit: Default::default(),
payer: None,
granter: None,
}
}
fn single_unspecified_signer_auth(
public_key: Option<tx::SignerPublicKey>,
sequence_number: tx::SequenceNumber,
) -> tx::AuthInfo {
tx::SignerInfo {
public_key,
mode_info: tx::ModeInfo::Single(tx::mode_info::Single {
mode: SignMode::Unspecified,
}),
sequence: sequence_number,
}
.auth_info(empty_fee())
}
#[async_trait]
pub trait SigningCosmWasmClient: CosmWasmClient {
fn signer(&self) -> &DirectSecp256k1HdWallet;
@@ -64,33 +76,21 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
let sequence_response = self.get_sequence(signer_address).await?;
let partial_tx = Tx {
body: tx::Body {
messages,
memo: memo.into(),
timeout_height: 0u32.into(),
extension_options: vec![],
non_critical_extension_options: vec![],
},
auth_info: tx::AuthInfo {
signer_infos: vec![tx::SignerInfo {
public_key,
mode_info: tx::ModeInfo::Single(tx::mode_info::Single {
mode: SignMode::Unspecified,
}),
sequence: sequence_response.sequence,
}],
fee: tx::Fee::from_amount_and_gas(
CosmosCoin {
denom: "".parse().unwrap(),
amount: 0u64.into(),
},
0,
),
},
signatures: vec![DUMMY_SECP256K1_SIGNATURE.try_into().unwrap()],
body: tx::Body::new(messages, memo, 0u32),
auth_info: single_unspecified_signer_auth(public_key, sequence_response.sequence),
signatures: vec![Vec::new()],
};
self.query_simulate(Some(partial_tx), Vec::new()).await
// for completion sake, once we're able to transition into using `tx_bytes`,
// we might want to use something like this instead:
// let tx_raw: tx::Raw = cosmrs::proto::cosmos::tx::v1beta1::TxRaw {
// body_bytes: partial_tx.body.into_bytes().unwrap(),
// auth_info_bytes: partial_tx.auth_info.into_bytes().unwrap(),
// signatures: partial_tx.signatures,
// }
// .into();
// self.query_simulate(None, tx_raw.to_bytes().unwrap()).await
}
async fn upload(
@@ -310,7 +310,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
sender: sender_address.clone(),
contract: contract_address.clone(),
msg: serde_json::to_vec(msg)?,
funds,
funds: funds.into_iter().map(Into::into).collect(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgExecuteContract".to_owned()))?;
@@ -349,7 +349,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
sender: sender_address.clone(),
contract: contract_address.clone(),
msg: serde_json::to_vec(&msg)?,
funds,
funds: funds.into_iter().map(Into::into).collect(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgExecuteContract".to_owned()))
@@ -382,7 +382,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
let send_msg = MsgSend {
from_address: sender_address.clone(),
to_address: recipient_address.clone(),
amount,
amount: amount.into_iter().map(Into::into).collect(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgSend".to_owned()))?;
@@ -408,7 +408,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
MsgSend {
from_address: sender_address.clone(),
to_address,
amount,
amount: amount.into_iter().map(Into::into).collect(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgExecuteContract".to_owned()))
@@ -431,7 +431,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
let delegate_msg = MsgDelegate {
delegator_address: delegator_address.to_owned(),
validator_address: validator_address.to_owned(),
amount,
amount: amount.into(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgDelegate".to_owned()))?;
@@ -452,7 +452,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
let undelegate_msg = MsgUndelegate {
delegator_address: delegator_address.to_owned(),
validator_address: validator_address.to_owned(),
amount: Some(amount),
amount: amount.into(),
}
.to_any()
.map_err(|_| NymdError::SerializationError("MsgUndelegate".to_owned()))?;
@@ -28,7 +28,7 @@ use cosmrs::proto::cosmwasm::wasm::v1::{
use cosmrs::tendermint::abci::Data;
use cosmrs::tendermint::{abci, chain};
use cosmrs::tx::{AccountNumber, Gas, SequenceNumber};
use cosmrs::{tx, AccountId, Any, Coin};
use cosmrs::{tx, AccountId, Any, Coin as CosmosCoin};
use prost::Message;
use serde::Serialize;
use std::convert::{TryFrom, TryInto};
@@ -107,9 +107,9 @@ impl TryFrom<ProtoModuleAccount> for ModuleAccount {
#[derive(Debug)]
pub struct BaseVestingAccount {
pub base_account: Option<BaseAccount>,
pub original_vesting: Vec<Coin>,
pub delegated_free: Vec<Coin>,
pub delegated_vesting: Vec<Coin>,
pub original_vesting: Vec<CosmosCoin>,
pub delegated_free: Vec<CosmosCoin>,
pub delegated_vesting: Vec<CosmosCoin>,
pub end_time: i64,
}
@@ -184,7 +184,7 @@ impl TryFrom<ProtoDelayedVestingAccount> for DelayedVestingAccount {
#[derive(Debug)]
pub struct Period {
pub length: i64,
pub amount: Vec<Coin>,
pub amount: Vec<CosmosCoin>,
}
impl TryFrom<ProtoPeriod> for Period {
@@ -489,7 +489,7 @@ impl TryFrom<ProtoContractCodeHistoryEntry> for ContractCodeHistoryEntry {
}
}
#[derive(Debug)]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct GasInfo {
/// GasWanted is the maximum units of work we allow this tx to perform.
pub gas_wanted: Gas,
@@ -628,7 +628,7 @@ pub struct InstantiateOptions {
/// created and before the instantiation message is executed by the contract.
///
/// Only native tokens are supported.
pub funds: Vec<Coin>,
pub funds: Vec<CosmosCoin>,
/// A bech32 encoded address of an admin account.
/// Caution: an admin has the privilege to upgrade a contract.
@@ -636,6 +636,15 @@ pub struct InstantiateOptions {
pub admin: Option<AccountId>,
}
impl InstantiateOptions {
pub fn new<T: Into<CosmosCoin>>(funds: Vec<T>, admin: Option<AccountId>) -> Self {
InstantiateOptions {
funds: funds.into_iter().map(Into::into).collect(),
admin,
}
}
}
#[derive(Debug)]
pub struct InstantiateResult {
/// The address of the newly instantiated contract
@@ -21,9 +21,12 @@ pub enum NymdError {
#[error("There was an issue with bip32 - {0}")]
Bip32Error(#[from] bip32::Error),
#[error("There was an issue with bip32 - {0}")]
#[error("There was an issue with bip39 - {0}")]
Bip39Error(#[from] bip39::Error),
#[error("There was an issue on the cosmrs side - {0}")]
CosmrsError(#[from] cosmrs::Error),
#[error("Failed to derive account address")]
AccountDerivationError,
@@ -39,10 +42,10 @@ pub enum NymdError {
#[error("There was an issue with a tendermint RPC request - {0}")]
TendermintError(#[from] TendermintRpcError),
#[error("There was an issue when attempting to serialize data")]
#[error("There was an issue when attempting to serialize data ({0})")]
SerializationError(String),
#[error("There was an issue when attempting to deserialize data")]
#[error("There was an issue when attempting to deserialize data ({0})")]
DeserializationError(String),
#[error("There was an issue when attempting to encode our protobuf data - {0}")]
@@ -121,6 +124,12 @@ pub enum NymdError {
#[error("Transaction with ID {hash} has been submitted but not yet found on the chain. You might want to check for it later. There was a total wait of {} seconds", .timeout.as_secs())]
BroadcastTimeout { hash: tx::Hash, timeout: Duration },
#[error("Cosmwasm std error: {0}")]
CosmwasmStdError(#[from] cosmwasm_std::StdError),
#[error("Coconut interface error: {0}")]
CoconutInterfaceError(#[from] coconut_interface::error::CoconutInterfaceError),
}
impl NymdError {
@@ -4,7 +4,7 @@
use crate::nymd::error::NymdError;
use config::defaults;
use cosmrs::tx::Gas;
use cosmrs::{Coin, Denom};
use cosmrs::Coin;
use cosmwasm_std::{Decimal, Fraction, Uint128};
use std::ops::Mul;
use std::str::FromStr;
@@ -13,11 +13,12 @@ use std::str::FromStr;
/// the smallest fee token unit, such as 0.012utoken.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct GasPrice {
// I really hate the combination of cosmwasm Decimal with cosmos-sdk Denom,
// but cosmos-sdk's Decimal is too basic for our needs
// I really dislike the usage of cosmwasm Decimal, but I didn't feel like implementing
// our own maths subcrate just for the purposes of calculating gas requirements
// this should definitely be rectified later on
pub amount: Decimal,
pub denom: Denom,
pub denom: String,
}
impl<'a> Mul<Gas> for &'a GasPrice {
@@ -44,7 +45,10 @@ impl<'a> Mul<Gas> for &'a GasPrice {
assert!(amount.u128() <= u64::MAX as u128);
Coin {
denom: self.denom.clone(),
denom: self
.denom
.parse()
.expect("the gas price has been created with invalid denom"),
amount: (amount.u128() as u64).into(),
}
}
@@ -63,9 +67,7 @@ impl FromStr for GasPrice {
.parse()
.map_err(|_| NymdError::MalformedGasPrice)?;
let possible_denom = s.chars().skip(amount_len).collect::<String>();
let denom = possible_denom
.parse()
.map_err(|_| NymdError::MalformedGasPrice)?;
let denom = possible_denom.trim().to_string();
Ok(GasPrice { amount, denom })
}
@@ -106,8 +108,14 @@ mod tests {
);
assert!(".25upunk".parse::<GasPrice>().is_err());
assert!("0.025 upunk".parse::<GasPrice>().is_err());
assert!("0.025UPUNK".parse::<GasPrice>().is_err());
assert_eq!(
"0.025upunk".parse::<GasPrice>().unwrap(),
"0.025 upunk".parse().unwrap()
);
let gas: GasPrice = "0.025 upunk ".parse().unwrap();
assert_eq!("upunk", gas.denom);
}
#[test]
@@ -1,195 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::GasPrice;
use cosmrs::tx::{Fee, Gas};
use cosmrs::Coin;
use serde::{Deserialize, Serialize};
use std::fmt;
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(
test,
ts(export, export_to = "../../../nym-wallet/src/types/rust/operation.ts")
)]
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum Operation {
Upload,
Init,
Migrate,
ChangeAdmin,
Send,
BondMixnode,
BondMixnodeOnBehalf,
UnbondMixnode,
UnbondMixnodeOnBehalf,
UpdateMixnodeConfig,
DelegateToMixnode,
DelegateToMixnodeOnBehalf,
UndelegateFromMixnode,
UndelegateFromMixnodeOnBehalf,
BondGateway,
BondGatewayOnBehalf,
UnbondGateway,
UnbondGatewayOnBehalf,
UpdateContractSettings,
BeginMixnodeRewarding,
FinishMixnodeRewarding,
TrackUnbondGateway,
TrackUnbondMixnode,
WithdrawVestedCoins,
TrackUndelegation,
CreatePeriodicVestingAccount,
AdvanceCurrentInterval,
AdvanceCurrentEpoch,
WriteRewardedSet,
ClearRewardedSet,
UpdateMixnetAddress,
CheckpointMixnodes,
ReconcileDelegations,
}
pub(crate) fn calculate_fee(gas_price: &GasPrice, gas_limit: Gas) -> Coin {
gas_price * gas_limit
}
impl fmt::Display for Operation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Operation::Upload => f.write_str("Upload"),
Operation::Init => f.write_str("Init"),
Operation::Migrate => f.write_str("Migrate"),
Operation::ChangeAdmin => f.write_str("ChangeAdmin"),
Operation::Send => f.write_str("Send"),
Operation::BondMixnode => f.write_str("BondMixnode"),
Operation::BondMixnodeOnBehalf => f.write_str("BondMixnodeOnBehalf"),
Operation::UnbondMixnode => f.write_str("UnbondMixnode"),
Operation::UpdateMixnodeConfig => f.write_str("UpdateMixnodeConfig"),
Operation::UnbondMixnodeOnBehalf => f.write_str("UnbondMixnodeOnBehalf"),
Operation::BondGateway => f.write_str("BondGateway"),
Operation::BondGatewayOnBehalf => f.write_str("BondGatewayOnBehalf"),
Operation::UnbondGateway => f.write_str("UnbondGateway"),
Operation::UnbondGatewayOnBehalf => f.write_str("UnbondGatewayOnBehalf"),
Operation::DelegateToMixnode => f.write_str("DelegateToMixnode"),
Operation::DelegateToMixnodeOnBehalf => f.write_str("DelegateToMixnodeOnBehalf"),
Operation::UndelegateFromMixnode => f.write_str("UndelegateFromMixnode"),
Operation::UndelegateFromMixnodeOnBehalf => {
f.write_str("UndelegateFromMixnodeOnBehalf")
}
Operation::UpdateContractSettings => f.write_str("UpdateContractSettings"),
Operation::BeginMixnodeRewarding => f.write_str("BeginMixnodeRewarding"),
Operation::FinishMixnodeRewarding => f.write_str("FinishMixnodeRewarding"),
Operation::TrackUnbondGateway => f.write_str("TrackUnbondGateway"),
Operation::TrackUnbondMixnode => f.write_str("TrackUnbondMixnode"),
Operation::WithdrawVestedCoins => f.write_str("WithdrawVestedCoins"),
Operation::TrackUndelegation => f.write_str("TrackUndelegation"),
Operation::CreatePeriodicVestingAccount => f.write_str("CreatePeriodicVestingAccount"),
Operation::AdvanceCurrentInterval => f.write_str("AdvanceCurrentInterval"),
Operation::WriteRewardedSet => f.write_str("WriteRewardedSet"),
Operation::ClearRewardedSet => f.write_str("ClearRewardedSet"),
Operation::UpdateMixnetAddress => f.write_str("UpdateMixnetAddress"),
Operation::CheckpointMixnodes => f.write_str("CheckpointMixnodes"),
Operation::ReconcileDelegations => f.write_str("ReconcileDelegations"),
Operation::AdvanceCurrentEpoch => f.write_str("AdvanceCurrentEpoch"),
}
}
}
impl Operation {
// TODO: some value tweaking
pub fn default_gas_limit(&self) -> Gas {
match self {
Operation::Upload => 3_000_000u64.into(),
Operation::Init => 500_000u64.into(),
Operation::Migrate => 200_000u64.into(),
Operation::ChangeAdmin => 80_000u64.into(),
Operation::Send => 80_000u64.into(),
Operation::BondMixnode => 175_000u64.into(),
Operation::BondMixnodeOnBehalf => 200_000u64.into(),
Operation::UnbondMixnode => 175_000u64.into(),
Operation::UnbondMixnodeOnBehalf => 175_000u64.into(),
Operation::UpdateMixnodeConfig => 175_000u64.into(),
Operation::DelegateToMixnode => 175_000u64.into(),
Operation::DelegateToMixnodeOnBehalf => 175_000u64.into(),
Operation::UndelegateFromMixnode => 175_000u64.into(),
Operation::UndelegateFromMixnodeOnBehalf => 175_000u64.into(),
Operation::BondGateway => 175_000u64.into(),
Operation::BondGatewayOnBehalf => 200_000u64.into(),
Operation::UnbondGateway => 175_000u64.into(),
Operation::UnbondGatewayOnBehalf => 200_000u64.into(),
Operation::UpdateContractSettings => 175_000u64.into(),
Operation::BeginMixnodeRewarding => 175_000u64.into(),
Operation::FinishMixnodeRewarding => 175_000u64.into(),
Operation::TrackUnbondGateway => 175_000u64.into(),
Operation::TrackUnbondMixnode => 175_000u64.into(),
Operation::WithdrawVestedCoins => 175_000u64.into(),
Operation::TrackUndelegation => 175_000u64.into(),
Operation::CreatePeriodicVestingAccount => 175_000u64.into(),
Operation::AdvanceCurrentInterval => 175_000u64.into(),
Operation::WriteRewardedSet => 175_000u64.into(),
Operation::ClearRewardedSet => 175_000u64.into(),
Operation::UpdateMixnetAddress => 80_000u64.into(),
Operation::CheckpointMixnodes => 175_000u64.into(),
Operation::ReconcileDelegations => 500_000u64.into(),
Operation::AdvanceCurrentEpoch => 175_000u64.into(),
}
}
pub(crate) fn determine_custom_fee(gas_price: &GasPrice, gas_limit: Gas) -> Fee {
// we need to know 2 of the following 3 parameters (the third one is being implicit) in order to construct Fee:
// (source: https://docs.cosmos.network/v0.42/basics/gas-fees.html)
// - gas price
// - gas limit
// - fees
let fee = calculate_fee(gas_price, gas_limit);
Fee::from_amount_and_gas(fee, gas_limit)
}
pub fn default_fee(&self, gas_price: &GasPrice) -> Fee {
Self::determine_custom_fee(gas_price, self.default_gas_limit())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn calculating_fee() {
let expected = Coin {
denom: "upunk".parse().unwrap(),
amount: 1000u64.into(),
};
let gas_price = "1upunk".parse().unwrap();
let gas_limit = 1000u64.into();
assert_eq!(expected, calculate_fee(&gas_price, gas_limit));
let expected = Coin {
denom: "upunk".parse().unwrap(),
amount: 50u64.into(),
};
let gas_price = "0.05upunk".parse().unwrap();
let gas_limit = 1000u64.into();
assert_eq!(expected, calculate_fee(&gas_price, gas_limit));
let expected = Coin {
denom: "upunk".parse().unwrap(),
amount: 100000u64.into(),
};
let gas_price = "100upunk".parse().unwrap();
let gas_limit = 1000u64.into();
assert_eq!(expected, calculate_fee(&gas_price, gas_limit))
}
}
@@ -2,15 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
use cosmrs::tx;
use serde::{Deserialize, Serialize};
pub mod gas_price;
pub mod helpers;
pub const DEFAULT_SIMULATED_GAS_MULTIPLIER: f32 = 1.3;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Fee {
Manual(tx::Fee),
Manual(#[serde(with = "sealed::TxFee")] tx::Fee),
Auto(Option<f32>),
}
@@ -31,3 +31,91 @@ impl Default for Fee {
Fee::Auto(Some(DEFAULT_SIMULATED_GAS_MULTIPLIER))
}
}
// a workaround to provide serde implementation for tx::Fee. We don't want to ever expose any of those
// types to the public and ideally they will get replaced by proper implementation inside comrs
mod sealed {
use cosmrs::tx::{self, Gas};
use cosmrs::Coin as CosmosCoin;
use cosmrs::{AccountId, Decimal as CosmosDecimal, Denom as CosmosDenom};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
fn cosmos_denom_inner_getter(val: &CosmosDenom) -> String {
val.as_ref().to_string()
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "CosmosDenom")]
struct Denom(#[serde(getter = "cosmos_denom_inner_getter")] String);
impl From<Denom> for CosmosDenom {
fn from(val: Denom) -> Self {
val.0.parse().unwrap()
}
}
fn cosmos_decimal_inner_getter(val: &CosmosDecimal) -> u64 {
// haha, this code is so disgusting. I'll make a PR on cosmrs to slightly alleviate those issues...
// note: unwrap here is fine as the to_string is just returning a stringified u64 which, well, is a valid u64
val.to_string().parse().unwrap()
}
// at the time of writing it the current cosmrs' Decimal is extremely limited...
#[derive(Serialize, Deserialize)]
#[serde(remote = "CosmosDecimal")]
struct Decimal(#[serde(getter = "cosmos_decimal_inner_getter")] u64);
impl From<Decimal> for CosmosDecimal {
fn from(val: Decimal) -> Self {
val.0.into()
}
}
#[derive(Serialize, Deserialize, Clone)]
struct Coin {
#[serde(with = "Denom")]
denom: CosmosDenom,
#[serde(with = "Decimal")]
amount: CosmosDecimal,
}
impl From<Coin> for CosmosCoin {
fn from(val: Coin) -> Self {
CosmosCoin {
denom: val.denom,
amount: val.amount,
}
}
}
impl From<CosmosCoin> for Coin {
fn from(val: CosmosCoin) -> Self {
Coin {
denom: val.denom,
amount: val.amount,
}
}
}
fn coin_vec_ser<S: Serializer>(val: &[CosmosCoin], serializer: S) -> Result<S::Ok, S::Error> {
let vec: Vec<Coin> = val.iter().cloned().map(Into::into).collect();
vec.serialize(serializer)
}
fn coin_vec_deser<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<Vec<CosmosCoin>, D::Error> {
let vec: Vec<Coin> = Deserialize::deserialize(deserializer)?;
Ok(vec.iter().cloned().map(Into::into).collect())
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "tx::Fee")]
pub(super) struct TxFee {
#[serde(serialize_with = "coin_vec_ser")]
#[serde(deserialize_with = "coin_vec_deser")]
pub amount: Vec<CosmosCoin>,
pub gas_limit: Gas,
pub payer: Option<AccountId>,
pub granter: Option<AccountId>,
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,49 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
use crate::nymd::cosmwasm_client::types::ExecuteResult;
use crate::nymd::error::NymdError;
use crate::nymd::{Coin, Fee, NymdClient};
use coconut_bandwidth_contract_common::{deposit::DepositData, msg::ExecuteMsg};
use async_trait::async_trait;
#[async_trait]
pub trait CoconutBandwidthSigningClient {
async fn deposit(
&self,
amount: Coin,
info: String,
verification_key: String,
encryption_key: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
}
#[async_trait]
impl<C: SigningCosmWasmClient + Sync + Send> CoconutBandwidthSigningClient for NymdClient<C> {
async fn deposit(
&self,
amount: Coin,
info: String,
verification_key: String,
encryption_key: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::DepositFunds {
data: DepositData::new(info.to_string(), verification_key, encryption_key),
};
self.client
.execute(
self.address(),
self.coconut_bandwidth_contract_address(),
&req,
fee,
"CoconutBandwidth::Deposit",
vec![amount],
)
.await
}
}
@@ -1,8 +1,14 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
mod coconut_bandwidth_signing_client;
mod multisig_query_client;
mod multisig_signing_client;
mod vesting_query_client;
mod vesting_signing_client;
pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient;
pub use multisig_query_client::QueryClient;
pub use multisig_signing_client::MultisigSigningClient;
pub use vesting_query_client::VestingQueryClient;
pub use vesting_signing_client::VestingSigningClient;
@@ -0,0 +1,24 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::error::NymdError;
use crate::nymd::{CosmWasmClient, NymdClient};
use multisig_contract_common::msg::{ProposalResponse, QueryMsg};
use async_trait::async_trait;
#[async_trait]
pub trait QueryClient {
async fn get_proposal(&self, proposal_id: u64) -> Result<ProposalResponse, NymdError>;
}
#[async_trait]
impl<C: CosmWasmClient + Sync + Send> QueryClient for NymdClient<C> {
async fn get_proposal(&self, proposal_id: u64) -> Result<ProposalResponse, NymdError> {
let request = QueryMsg::Proposal { proposal_id };
self.client
.query_contract_smart(self.multisig_contract_address(), &request)
.await
}
}
@@ -0,0 +1,116 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
use crate::nymd::cosmwasm_client::types::ExecuteResult;
use crate::nymd::error::NymdError;
use crate::nymd::{Fee, NymdClient};
use coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg;
use multisig_contract_common::msg::ExecuteMsg;
use async_trait::async_trait;
use cosmwasm_std::{to_binary, Coin, CosmosMsg, WasmMsg};
use cw3::Vote;
use network_defaults::DEFAULT_NETWORK;
#[async_trait]
pub trait MultisigSigningClient {
async fn propose_release_funds(
&self,
title: String,
blinded_serial_number: String,
voucher_value: u128,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vote_proposal(
&self,
proposal_id: u64,
yes: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn execute_proposal(
&self,
proposal_id: u64,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
}
#[async_trait]
impl<C: SigningCosmWasmClient + Sync + Send> MultisigSigningClient for NymdClient<C> {
async fn propose_release_funds(
&self,
title: String,
blinded_serial_number: String,
voucher_value: u128,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let release_funds_req = CoconutBandwidthExecuteMsg::ReleaseFunds {
funds: Coin::new(voucher_value, DEFAULT_NETWORK.denom()),
};
let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: self.coconut_bandwidth_contract_address().to_string(),
msg: to_binary(&release_funds_req)?,
funds: vec![],
});
let req = ExecuteMsg::Propose {
title,
description: blinded_serial_number,
msgs: vec![release_funds_msg],
latest: None,
};
self.client
.execute(
self.address(),
self.multisig_contract_address(),
&req,
fee,
"Multisig::Propose::Execute::ReleaseFunds",
vec![],
)
.await
}
async fn vote_proposal(
&self,
proposal_id: u64,
vote_yes: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let vote = if vote_yes { Vote::Yes } else { Vote::No };
let req = ExecuteMsg::Vote { proposal_id, vote };
self.client
.execute(
self.address(),
self.multisig_contract_address(),
&req,
fee,
"Multisig::Vote",
vec![],
)
.await
}
async fn execute_proposal(
&self,
proposal_id: u64,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::Execute { proposal_id };
self.client
.execute(
self.address(),
self.multisig_contract_address(),
&req,
fee,
"Multisig::Execute",
vec![],
)
.await
}
}
@@ -1,11 +1,12 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::coin::Coin;
pub use crate::nymd::cosmwasm_client::client::CosmWasmClient;
use crate::nymd::error::NymdError;
use crate::nymd::NymdClient;
use async_trait::async_trait;
use cosmwasm_std::{Coin, Timestamp};
use cosmwasm_std::{Coin as CosmWasmCoin, Timestamp};
use vesting_contract::vesting::Account;
use vesting_contract_common::{
messages::QueryMsg as VestingQueryMsg, OriginalVestingResponse, Period, PledgeData,
@@ -83,8 +84,9 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
async fn spendable_coins(
@@ -97,8 +99,9 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
async fn vested_coins(
&self,
@@ -110,8 +113,9 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
async fn vesting_coins(
&self,
@@ -123,8 +127,9 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
async fn vesting_start_time(
@@ -135,7 +140,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
vesting_account_address: vesting_account_address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
@@ -147,7 +152,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
vesting_account_address: vesting_account_address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
@@ -159,7 +164,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
vesting_account_address: vesting_account_address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
@@ -173,10 +178,12 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
/// Returns the total amount of delegated tokens that have vested
async fn delegated_vesting(
&self,
vesting_account_address: &str,
@@ -187,8 +194,9 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
block_time,
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart::<_, CosmWasmCoin>(self.vesting_contract_address(), &request)
.await
.map(Into::into)
}
async fn get_account(&self, address: &str) -> Result<Account, NymdError> {
@@ -196,7 +204,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
async fn get_mixnode_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError> {
@@ -204,7 +212,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
async fn get_gateway_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError> {
@@ -212,7 +220,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
@@ -221,7 +229,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.query_contract_smart(self.vesting_contract_address(), &request)
.await
}
}
@@ -4,10 +4,8 @@
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
use crate::nymd::cosmwasm_client::types::ExecuteResult;
use crate::nymd::error::NymdError;
use crate::nymd::fee::helpers::Operation;
use crate::nymd::{cosmwasm_coin_to_cosmos_coin, NymdClient};
use crate::nymd::{Coin, Fee, NymdClient};
use async_trait::async_trait;
use cosmwasm_std::Coin;
use mixnet_contract_common::{Gateway, IdentityKey, IdentityKeyRef, MixNode};
use vesting_contract_common::messages::{ExecuteMsg as VestingExecuteMsg, VestingSpecification};
@@ -16,23 +14,30 @@ pub trait VestingSigningClient {
async fn vesting_update_mixnode_config(
&self,
profix_margin_percent: u8,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError>;
async fn update_mixnet_address(
&self,
address: &str,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_bond_gateway(
&self,
gateway: Gateway,
owner_signature: &str,
pledge: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_unbond_gateway(&self) -> Result<ExecuteResult, NymdError>;
async fn vesting_unbond_gateway(&self, fee: Option<Fee>) -> Result<ExecuteResult, NymdError>;
async fn vesting_track_unbond_gateway(
&self,
owner: &str,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_bond_mixnode(
@@ -40,33 +45,42 @@ pub trait VestingSigningClient {
mix_node: MixNode,
owner_signature: &str,
pledge: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_unbond_mixnode(&self) -> Result<ExecuteResult, NymdError>;
async fn vesting_unbond_mixnode(&self, fee: Option<Fee>) -> Result<ExecuteResult, NymdError>;
async fn vesting_track_unbond_mixnode(
&self,
owner: &str,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn withdraw_vested_coins(&self, amount: Coin) -> Result<ExecuteResult, NymdError>;
async fn withdraw_vested_coins(
&self,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_track_undelegation(
&self,
address: &str,
mix_identity: IdentityKey,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_delegate_to_mixnode<'a>(
&self,
mix_identity: IdentityKeyRef<'a>,
amount: &Coin,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_undelegate_from_mixnode<'a>(
&self,
mix_identity: IdentityKeyRef<'a>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn create_periodic_vesting_account(
@@ -75,27 +89,71 @@ pub trait VestingSigningClient {
staking_address: Option<String>,
vesting_spec: Option<VestingSpecification>,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
}
#[async_trait]
impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient<C> {
async fn vesting_update_mixnode_config(
&self,
profit_margin_percent: u8,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::UpdateMixnodeConfig {
profit_margin_percent,
};
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::UpdateMixnetConfig",
vec![],
)
.await
}
async fn update_mixnet_address(
&self,
address: &str,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::UpdateMixnetAddress {
address: address.to_string(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::UpdateMixnetAddress",
vec![],
)
.await
}
async fn vesting_bond_gateway(
&self,
gateway: Gateway,
owner_signature: &str,
pledge: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::BondGateway);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::BondGateway {
gateway,
owner_signature: owner_signature.to_string(),
amount: pledge,
amount: pledge.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::BondGateway",
@@ -104,13 +162,13 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
.await
}
async fn vesting_unbond_gateway(&self) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UnbondGateway);
async fn vesting_unbond_gateway(&self, fee: Option<Fee>) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::UnbondGateway {};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::UnbondGateway",
@@ -123,16 +181,17 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&self,
owner: &str,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::TrackUnbondGateway);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::TrackUnbondGateway {
owner: owner.to_string(),
amount,
amount: amount.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::TrackUnbondGateway",
@@ -146,17 +205,18 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
mix_node: MixNode,
owner_signature: &str,
pledge: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::BondMixnode);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::BondMixnode {
mix_node,
owner_signature: owner_signature.to_string(),
amount: pledge,
amount: pledge.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::BondMixnode",
@@ -165,13 +225,13 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
.await
}
async fn vesting_unbond_mixnode(&self) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UnbondMixnode);
async fn vesting_unbond_mixnode(&self, fee: Option<Fee>) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::UnbondMixnode {};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::UnbondMixnode",
@@ -184,16 +244,17 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&self,
owner: &str,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::TrackUnbondMixnode);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::TrackUnbondMixnode {
owner: owner.to_string(),
amount,
amount: amount.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::TrackUnbondMixnode",
@@ -201,14 +262,19 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn withdraw_vested_coins(&self, amount: Coin) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::WithdrawVestedCoins);
let req = VestingExecuteMsg::WithdrawVestedCoins { amount };
async fn withdraw_vested_coins(
&self,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::WithdrawVestedCoins {
amount: amount.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::WithdrawVested",
@@ -216,23 +282,23 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn vesting_track_undelegation(
&self,
address: &str,
mix_identity: IdentityKey,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::TrackUndelegation);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::TrackUndelegation {
owner: address.to_string(),
mix_identity,
amount,
amount: amount.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::TrackUndelegation",
@@ -243,17 +309,18 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
async fn vesting_delegate_to_mixnode<'a>(
&self,
mix_identity: IdentityKeyRef<'a>,
amount: &Coin,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::DelegateToMixnode);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::DelegateToMixnode {
mix_identity: mix_identity.into(),
amount: amount.clone(),
amount: amount.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::DelegateToMixnode",
@@ -261,18 +328,20 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn vesting_undelegate_from_mixnode<'a>(
&self,
mix_identity: IdentityKeyRef<'a>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UndelegateFromMixnode);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::UndelegateFromMixnode {
mix_identity: mix_identity.into(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::UndelegateFromMixnode",
@@ -280,14 +349,16 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn create_periodic_vesting_account(
&self,
owner_address: &str,
staking_address: Option<String>,
vesting_spec: Option<VestingSpecification>,
amount: Coin,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::CreatePeriodicVestingAccount);
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::CreateAccount {
owner_address: owner_address.to_string(),
staking_address,
@@ -296,48 +367,11 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
self.vesting_contract_address(),
&req,
fee,
"VestingContract::CreatePeriodicVestingAccount",
vec![cosmwasm_coin_to_cosmos_coin(amount)],
)
.await
}
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UpdateMixnetAddress);
let req = VestingExecuteMsg::UpdateMixnetAddress {
address: address.to_string(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
&req,
fee,
"VestingContract::UpdateMixnetAddress",
vec![],
)
.await
}
async fn vesting_update_mixnode_config(
&self,
profit_margin_percent: u8,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UpdateMixnodeConfig);
let req = VestingExecuteMsg::UpdateMixnodeConfig {
profit_margin_percent,
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
&req,
fee,
"VestingContract::UpdateMixnetConfig",
vec![],
vec![amount],
)
.await
}
@@ -3,14 +3,18 @@
use crate::validator_api::error::ValidatorAPIError;
use crate::validator_api::routes::{CORE_STATUS_COUNT, SINCE_ARG};
use coconut_interface::{BlindSignRequestBody, BlindedSignatureResponse, VerificationKeyResponse};
use coconut_interface::{
BlindSignRequestBody, BlindedSignatureResponse, ExecuteReleaseFundsRequestBody,
ProposeReleaseFundsRequestBody, ProposeReleaseFundsResponse, VerificationKeyResponse,
VerifyCredentialBody, VerifyCredentialResponse,
};
use mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixNodeBond};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use url::Url;
use validator_api_requests::models::{
CoreNodeStatusResponse, InclusionProbabilityResponse, MixnodeStatusResponse,
RewardEstimationResponse, StakeSaturationResponse, UptimeResponse,
CoreNodeStatusResponse, InclusionProbabilityResponse, MixNodeBondAnnotated,
MixnodeStatusResponse, RewardEstimationResponse, StakeSaturationResponse, UptimeResponse,
};
pub mod error;
@@ -85,6 +89,16 @@ impl Client {
.await
}
pub async fn get_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorAPIError> {
self.query_validator_api(
&[routes::API_VERSION, routes::MIXNODES, routes::DETAILED],
NO_PARAMS,
)
.await
}
pub async fn get_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorAPIError> {
self.query_validator_api(&[routes::API_VERSION, routes::GATEWAYS], NO_PARAMS)
.await
@@ -98,6 +112,21 @@ impl Client {
.await
}
pub async fn get_active_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorAPIError> {
self.query_validator_api(
&[
routes::API_VERSION,
routes::MIXNODES,
routes::ACTIVE,
routes::DETAILED,
],
NO_PARAMS,
)
.await
}
pub async fn get_rewarded_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorAPIError> {
self.query_validator_api(
&[routes::API_VERSION, routes::MIXNODES, routes::REWARDED],
@@ -106,6 +135,21 @@ impl Client {
.await
}
pub async fn get_rewarded_mixnodes_detailed(
&self,
) -> Result<Vec<MixNodeBondAnnotated>, ValidatorAPIError> {
self.query_validator_api(
&[
routes::API_VERSION,
routes::MIXNODES,
routes::REWARDED,
routes::DETAILED,
],
NO_PARAMS,
)
.await
}
pub async fn get_probs_mixnode_rewarded(
&self,
mixnode_id: &str,
@@ -331,6 +375,57 @@ impl Client {
)
.await
}
pub async fn verify_bandwidth_credential(
&self,
request_body: &VerifyCredentialBody,
) -> Result<VerifyCredentialResponse, ValidatorAPIError> {
self.post_validator_api(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_VERIFY_BANDWIDTH_CREDENTIAL,
],
NO_PARAMS,
request_body,
)
.await
}
pub async fn propose_release_funds(
&self,
request_body: &ProposeReleaseFundsRequestBody,
) -> Result<ProposeReleaseFundsResponse, ValidatorAPIError> {
self.post_validator_api(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_PROPOSE_RELEASE_FUNDS,
],
NO_PARAMS,
request_body,
)
.await
}
pub async fn execute_release_funds(
&self,
request_body: &ExecuteReleaseFundsRequestBody,
) -> Result<(), ValidatorAPIError> {
self.post_validator_api(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_EXECUTE_RELEASE_FUNDS,
],
NO_PARAMS,
request_body,
)
.await
}
}
// utility function that should solve the double slash problem in validator API forever.
@@ -7,6 +7,7 @@ pub const API_VERSION: &str = VALIDATOR_API_VERSION;
pub const MIXNODES: &str = "mixnodes";
pub const GATEWAYS: &str = "gateways";
pub const DETAILED: &str = "detailed";
pub const ACTIVE: &str = "active";
pub const REWARDED: &str = "rewarded";
@@ -16,6 +17,9 @@ pub const BANDWIDTH: &str = "bandwidth";
pub const COCONUT_BLIND_SIGN: &str = "blind-sign";
pub const COCONUT_PARTIAL_BANDWIDTH_CREDENTIAL: &str = "partial-bandwidth-credential";
pub const COCONUT_VERIFICATION_KEY: &str = "verification-key";
pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential";
pub const COCONUT_PROPOSE_RELEASE_FUNDS: &str = "propose-release-funds";
pub const COCONUT_EXECUTE_RELEASE_FUNDS: &str = "execute-release-funds";
pub const STATUS_ROUTES: &str = "status";
pub const MIXNODE: &str = "mixnode";
+3 -5
View File
@@ -1,6 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nymcoconut::CoconutError;
use thiserror::Error;
#[derive(Debug, Error)]
@@ -11,9 +12,6 @@ pub enum CoconutInterfaceError {
#[error("Could not decode base 58 string - {0}")]
MalformedString(#[from] bs58::decode::Error),
#[error("Not enough public attributes were specified")]
NotEnoughPublicAttributes,
#[error("Could not recover bandwidth value")]
InvalidBandwidth,
#[error("Coconut error - {0}")]
CoconutError(#[from] CoconutError),
}
+191 -46
View File
@@ -5,96 +5,158 @@ pub mod error;
use getset::{CopyGetters, Getters};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use error::CoconutInterfaceError;
pub use nymcoconut::*;
#[derive(Serialize, Deserialize, Getters, CopyGetters, Clone)]
#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq)]
pub struct Credential {
#[getset(get = "pub")]
n_params: u32,
#[getset(get = "pub")]
theta: Theta,
public_attributes: Vec<Vec<u8>>,
#[getset(get = "pub")]
signature: Signature,
voucher_value: u64,
voucher_info: String,
}
impl Credential {
pub fn new(
n_params: u32,
theta: Theta,
voucher_value: String,
voucher_value: u64,
voucher_info: String,
signature: &Signature,
) -> Credential {
let public_attributes = vec![voucher_value.into_bytes(), voucher_info.into_bytes()];
Credential {
n_params,
theta,
public_attributes,
signature: *signature,
voucher_value,
voucher_info,
}
}
pub fn voucher_value(&self) -> Result<u64, CoconutInterfaceError> {
let bandwidth_vec = self
.public_attributes
.get(0)
.ok_or(CoconutInterfaceError::NotEnoughPublicAttributes)?
.to_owned();
let bandwidth_str = String::from_utf8(bandwidth_vec)
.map_err(|_| CoconutInterfaceError::InvalidBandwidth)?;
let value =
u64::from_str(&bandwidth_str).map_err(|_| CoconutInterfaceError::InvalidBandwidth)?;
pub fn blinded_serial_number(&self) -> String {
self.theta.blinded_serial_number_bs58()
}
Ok(value)
pub fn has_blinded_serial_number(
&self,
blinded_serial_number_bs58: &str,
) -> Result<bool, CoconutInterfaceError> {
Ok(self
.theta
.has_blinded_serial_number(blinded_serial_number_bs58)?)
}
pub fn voucher_value(&self) -> u64 {
self.voucher_value
}
pub fn verify(&self, verification_key: &VerificationKey) -> bool {
let params = Parameters::new(self.n_params).unwrap();
let public_attributes = self
.public_attributes
.iter()
.map(hash_to_scalar)
.collect::<Vec<Attribute>>();
let public_attributes = vec![
self.voucher_value.to_string().as_bytes(),
self.voucher_info.as_bytes(),
]
.iter()
.map(hash_to_scalar)
.collect::<Vec<Attribute>>();
nymcoconut::verify_credential(&params, verification_key, &self.theta, &public_attributes)
}
pub fn as_bytes(&self) -> Vec<u8> {
let n_params_bytes = self.n_params.to_be_bytes();
let theta_bytes = self.theta.to_bytes();
let theta_bytes_len = theta_bytes.len();
let voucher_value_bytes = self.voucher_value.to_be_bytes();
let voucher_info_bytes = self.voucher_info.as_bytes();
let voucher_info_len = voucher_info_bytes.len();
let mut bytes = Vec::with_capacity(28 + theta_bytes_len + voucher_info_len);
bytes.extend_from_slice(&n_params_bytes);
bytes.extend_from_slice(&(theta_bytes_len as u64).to_be_bytes());
bytes.extend_from_slice(&theta_bytes);
bytes.extend_from_slice(&voucher_value_bytes);
bytes.extend_from_slice(voucher_info_bytes);
bytes
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CoconutError> {
if bytes.len() < 28 {
return Err(CoconutError::Deserialization(String::from(
"To few bytes in credential",
)));
}
let mut four_byte = [0u8; 4];
let mut eight_byte = [0u8; 8];
four_byte.copy_from_slice(&bytes[..4]);
let n_params = u32::from_be_bytes(four_byte);
eight_byte.copy_from_slice(&bytes[4..12]);
let theta_len = u64::from_be_bytes(eight_byte);
if bytes.len() < 28 + theta_len as usize {
return Err(CoconutError::Deserialization(String::from(
"To few bytes in credential",
)));
}
let theta = Theta::from_bytes(&bytes[12..12 + theta_len as usize])
.map_err(|e| CoconutError::Deserialization(e.to_string()))?;
eight_byte.copy_from_slice(&bytes[12 + theta_len as usize..20 + theta_len as usize]);
let voucher_value = u64::from_be_bytes(eight_byte);
let voucher_info = String::from_utf8(bytes[20 + theta_len as usize..].to_vec())
.map_err(|e| CoconutError::Deserialization(e.to_string()))?;
Ok(Credential {
n_params,
theta,
voucher_value,
voucher_info,
})
}
}
#[derive(Serialize, Deserialize, Debug, Getters, CopyGetters)]
impl Bytable for Credential {
fn to_byte_vec(&self) -> Vec<u8> {
self.as_bytes()
}
fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CoconutError> {
Credential::from_bytes(slice)
}
}
impl Base58 for Credential {}
#[derive(Serialize, Deserialize, Getters, CopyGetters)]
pub struct VerifyCredentialBody {
#[getset(get = "pub")]
n_params: u32,
credential: Credential,
#[getset(get = "pub")]
theta: Theta,
public_attributes: Vec<String>,
proposal_id: u64,
}
impl VerifyCredentialBody {
pub fn new(
n_params: u32,
theta: &Theta,
public_attributes: &[Attribute],
) -> VerifyCredentialBody {
pub fn new(credential: Credential, proposal_id: u64) -> VerifyCredentialBody {
VerifyCredentialBody {
n_params,
theta: theta.clone(),
public_attributes: public_attributes
.iter()
.map(|attr| attr.to_bs58())
.collect(),
credential,
proposal_id,
}
}
}
pub fn public_attributes(&self) -> Vec<Attribute> {
self.public_attributes
.iter()
.map(|x| Attribute::try_from_bs58(x).unwrap())
.collect()
#[derive(Debug, Serialize, Deserialize)]
pub struct VerifyCredentialResponse {
pub verification_result: bool,
}
impl VerifyCredentialResponse {
pub fn new(verification_result: bool) -> Self {
VerifyCredentialResponse {
verification_result,
}
}
}
// All strings are base58 encoded representations of structs
#[derive(Clone, Serialize, Deserialize, Debug, Getters, CopyGetters)]
pub struct BlindSignRequestBody {
@@ -194,3 +256,86 @@ impl VerificationKeyResponse {
VerificationKeyResponse { key }
}
}
#[derive(Serialize, Deserialize, Getters, CopyGetters)]
pub struct ProposeReleaseFundsRequestBody {
#[getset(get = "pub")]
credential: Credential,
}
impl ProposeReleaseFundsRequestBody {
pub fn new(credential: Credential) -> Self {
ProposeReleaseFundsRequestBody { credential }
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ProposeReleaseFundsResponse {
pub proposal_id: u64,
}
impl ProposeReleaseFundsResponse {
pub fn new(proposal_id: u64) -> Self {
ProposeReleaseFundsResponse { proposal_id }
}
}
#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters)]
pub struct ExecuteReleaseFundsRequestBody {
#[getset(get = "pub")]
proposal_id: u64,
}
impl ExecuteReleaseFundsRequestBody {
pub fn new(proposal_id: u64) -> Self {
ExecuteReleaseFundsRequestBody { proposal_id }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serde_coconut_credential() {
let voucher_value = 1000000u64;
let voucher_info = String::from("BandwidthVoucher");
let serial_number =
Attribute::try_from_bs58("7Rp3imcuNX3w9se9wm5th8gSvc2czsnMrGsdt5HsrycA").unwrap();
let binding_number =
Attribute::try_from_bs58("Auf8yVEgyEAWNHaXUZmimS4n9g5YiYnNYqp6F9BtBe9E").unwrap();
let signature = Signature::try_from_bs58(
"ta3pM9ffj5T6YGbwjSBp2W118rcwyP9PXStc\
7ssb91g5GQYMQHhuTNajbdZcjxUFBFL5rhED8EHpRzE8r432ss3qbPBfpNev4CdkfMkQ3wepyM7hy7q1W6Rn9WmFoZL\
ZR9j",
)
.unwrap();
let params = Parameters::new(4).unwrap();
let verification_key = VerificationKey::try_from_bs58("8CFtVVXdwLy4WHMQPE4\
woe89q3DRHoNxBSchftrEjSBPWA4r4xZv4Y9qSvS5x5bMmFtp7BX6ikECAnuXr5EjXWSsgjirZJmpS5XDUynVfht1cD\
FWGDvy2XFrRCuoCMotNXi3PoF6wYqdTR9Rqcfoj3i2H5Nid422WBaLtVoC9QNobvpvaqq6vX5PbsSyPayvU8HCXFxM6\
JjScYpbRTxQtdwefWLrk3LmXyJQBWi7c2VAhSxu9msp7VTBycqdwQNgxHETStZuwXsozxaGQ2KssVUCaaoYPR4g2RqK\
UAvtWwA7pMiAQNcbkXcbsjCgVjWaCpMWC37XA31cLcFf3zbjHD9e5tXjAcqa4M89fbFhuvvSXxowSAZ5NoWrN32kd5d\
wxJm1JW3Tt2h6yDDBe84oMy71462dZn7N78DVk2mFNGwBCibrZWA7oUzRBMfYxiQrksoFcou7QfLLd58zoNYmPQPt84\
1VpQopEBfdQ7Nf9zoXxBt3zMy7g5NsFGvzh7KTbDUyeeXrdkKJPQBs6dqaizr9sS8CPPmR4uk96vDTRh8CJ5FbSsmb8\
nP71dRvvwRZJHGzwYirMo6SXS3ZYxFuiA3mkxYuqDHCwkTWDuRCcAaztrDYRZg7VCMo4Q446AaEso5eqpeWpHZQt53E\
ZRpqmNYKASGwMhTeEHPSLgSmtoAAUcaRWpGRzYfd6kzEma8tdGLwyP4rLXgvSvtDLP37dU7YgF3LEXbGAz57U9ATy46\
6sroLpHPdaCWB8RF11wvB6Tu196JnJd2KyQBP1iUWP3rtZs3GhAF1QVcxquh8BqDZzAcpQ6wCS1P9c5GxKgww77FVF5\
Kp83XtoxSrw3GaYVyKTGxNh3vcKPR31txCjTxPaN2fg7TaPLhoQJX4YaAroFSXqrqbbRsisuHhhCeUP2YwDjHedes9y")
.unwrap();
let theta = prove_bandwidth_credential(
&params,
&verification_key,
&signature,
serial_number,
binding_number,
)
.unwrap();
let credential = Credential::new(4, theta, voucher_value, voucher_info);
let serialized_credential = credential.as_bytes();
let deserialized_credential = Credential::from_bytes(&serialized_credential).unwrap();
assert_eq!(credential, deserialized_credential);
}
}
-4
View File
@@ -15,7 +15,6 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
fn template() -> &'static str;
fn config_file_name() -> String {
log::trace!("NymdConfig::config_file_name");
"config.toml".to_string()
}
@@ -23,7 +22,6 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
// default, most probable, implementations; can be easily overridden where required
fn default_config_directory(id: Option<&str>) -> PathBuf {
log::trace!("NymdConfig::default_config_directory");
if let Some(id) = id {
Self::default_root_directory().join(id).join("config")
} else {
@@ -32,7 +30,6 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
}
fn default_data_directory(id: Option<&str>) -> PathBuf {
log::trace!("NymdConfig::default_data_path");
if let Some(id) = id {
Self::default_root_directory().join(id).join("data")
} else {
@@ -41,7 +38,6 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
}
fn default_config_file_path(id: Option<&str>) -> PathBuf {
log::trace!("NymdConfig::default_config_file_path");
Self::default_config_directory(id).join(Self::config_file_name())
}
@@ -6,6 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-std = "1.0.0-beta6"
cosmwasm-std = "1.0.0"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
@@ -7,4 +7,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-std = "1.0.0-beta8"
cosmwasm-std = "1.0.0"
@@ -7,7 +7,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-std = "1.0.0-beta8"
cosmwasm-std = "1.0.0"
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1"
@@ -18,12 +18,13 @@ fixed = { version = "1.1", features = ["serde"] }
az = "1.1"
log = "0.4.14"
time = { version = "0.3.6", features = ["parsing", "formatting"] }
ts-rs = "6.1.2"
contracts-common = { path = "../contracts-common" }
[dev-dependencies]
time = { version = "0.3.5", features = ["serde", "macros"] }
ts-rs = "6.1.2"
[features]
default = []
generate-ts = []
@@ -23,7 +23,9 @@ pub const CHANGE_REWARDED_SET_EVENT_TYPE: &str = "change_rewarded_set";
pub const ADVANCE_INTERVAL_EVENT_TYPE: &str = "advance_interval";
pub const ADVANCE_EPOCH_EVENT_TYPE: &str = "advance_epoch";
pub const COMPOUND_DELEGATOR_REWARD_EVENT_TYPE: &str = "compound_delegator_reward";
pub const CLAIM_DELEGATOR_REWARD_EVENT_TYPE: &str = "claim_delegator_reward";
pub const COMPOUND_OPERATOR_REWARD_EVENT_TYPE: &str = "compound_operator_reward";
pub const CLAIM_OPERATOR_REWARD_EVENT_TYPE: &str = "claim_operator_reward";
pub const SNAPSHOT_MIXNODES_EVENT: &str = "snapshot_mixnodes";
// attributes that are used in multiple places
@@ -151,6 +153,11 @@ pub fn new_compound_operator_reward_event(owner: &Addr, amount: Uint128) -> Even
event.add_attribute(AMOUNT_KEY, amount.to_string())
}
pub fn new_claim_operator_reward_event(owner: &Addr, amount: Uint128) -> Event {
let event = Event::new(CLAIM_OPERATOR_REWARD_EVENT_TYPE).add_attribute(OWNER_KEY, owner);
event.add_attribute(AMOUNT_KEY, amount.to_string())
}
pub fn new_compound_delegator_reward_event(
delegator: &Addr,
proxy: &Option<Addr>,
@@ -171,6 +178,26 @@ pub fn new_compound_delegator_reward_event(
.add_attribute(DELEGATOR_KEY, delegator)
}
pub fn new_claim_delegator_reward_event(
delegator: &Addr,
proxy: &Option<Addr>,
amount: Uint128,
mix_identity: IdentityKeyRef<'_>,
) -> Event {
let mut event =
Event::new(CLAIM_DELEGATOR_REWARD_EVENT_TYPE).add_attribute(DELEGATOR_KEY, delegator);
if let Some(proxy) = proxy {
event = event.add_attribute(PROXY_KEY, proxy)
}
// coin implements Display trait and we use that implementation here
event
.add_attribute(AMOUNT_KEY, amount.to_string())
.add_attribute(DELEGATION_TARGET_KEY, mix_identity)
.add_attribute(DELEGATOR_KEY, delegator)
}
pub fn new_undelegation_event(
delegator: &Addr,
proxy: &Option<Addr>,
@@ -8,11 +8,6 @@ use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt::Display;
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(
test,
ts(export, export_to = "../../../nym-wallet/src/types/rust/gateway.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub struct Gateway {
pub host: String,
@@ -14,13 +14,10 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
use std::cmp::Ordering;
use std::fmt::Display;
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
test,
ts(
export,
export_to = "../../../nym-wallet/src/types/rust/rewardedsetnodestatus.ts"
)
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts")
)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
pub enum RewardedSetNodeStatus {
@@ -109,11 +106,6 @@ impl PendingUndelegate {
}
}
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(
test,
ts(export, export_to = "../../../nym-wallet/src/types/rust/mixnode.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub struct MixNode {
pub host: String,
@@ -228,9 +220,9 @@ impl DelegatorRewardParams {
// change all values into their fixed representations
let delegation_amount = U128::from_num(delegation_amount.u128());
let circulating_supply = U128::from_num(self.reward_params.circulating_supply());
let staking_supply = U128::from_num(self.reward_params.staking_supply());
let scaled_delegation_amount = delegation_amount / circulating_supply;
let scaled_delegation_amount = delegation_amount / staking_supply;
// Div by zero checked above
let delegator_reward =
@@ -318,6 +310,14 @@ impl NodeRewardResult {
}
}
pub struct RewardEstimate {
pub total_node_reward: u64,
pub operator_reward: u64,
pub delegators_reward: u64,
pub node_profit: u64,
pub operator_cost: u64,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct MixNodeBond {
pub pledge_amount: Coin,
@@ -392,81 +392,97 @@ impl MixNodeBond {
self.total_delegation.clone()
}
pub fn stake_saturation(&self, circulating_supply: u128, rewarded_set_size: u32) -> U128 {
self.total_bond_to_circulating_supply(circulating_supply)
* U128::from_num(rewarded_set_size)
pub fn stake_saturation(&self, staking_supply: u128, rewarded_set_size: u32) -> U128 {
self.total_bond_to_staking_supply(staking_supply) * U128::from_num(rewarded_set_size)
}
// TODO: There is an effect here when adding accumulted rewards to the total bond, ie accumulated rewards will not
// affect lambda, but will affect sigma, in turn over time, if left unclaimed operator rewards will not compound, but
// behave similarly to delegations.
// The question is should this be taken into account when calculating operator rewards?
pub fn pledge_to_circulating_supply(&self, circulating_supply: u128) -> U128 {
U128::from_num(self.pledge_amount().amount.u128()) / U128::from_num(circulating_supply)
pub fn pledge_to_staking_supply(&self, staking_supply: u128) -> U128 {
U128::from_num(self.pledge_amount().amount.u128()) / U128::from_num(staking_supply)
}
pub fn total_bond_to_circulating_supply(&self, circulating_supply: u128) -> U128 {
pub fn total_bond_to_staking_supply(&self, staking_supply: u128) -> U128 {
U128::from_num(self.pledge_amount().amount.u128() + self.total_delegation().amount.u128())
/ U128::from_num(circulating_supply)
/ U128::from_num(staking_supply)
}
pub fn lambda_ticked(&self, params: &RewardParams) -> U128 {
// Ratio of a bond to the token circulating supply
self.lambda(params).min(params.one_over_k())
}
pub fn lambda(&self, params: &RewardParams) -> U128 {
// Ratio of a bond to the token circulating supply
let pledge_to_circulating_supply_ratio =
self.pledge_to_circulating_supply(params.circulating_supply());
pledge_to_circulating_supply_ratio.min(params.one_over_k())
self.pledge_to_staking_supply(params.staking_supply())
}
pub fn sigma_ticked(&self, params: &RewardParams) -> U128 {
// Ratio of a delegation to the the token circulating supply
self.sigma(params).min(params.one_over_k())
}
pub fn sigma(&self, params: &RewardParams) -> U128 {
// Ratio of a delegation to the the token circulating supply
let total_bond_to_circulating_supply_ratio =
self.total_bond_to_circulating_supply(params.circulating_supply());
total_bond_to_circulating_supply_ratio.min(params.one_over_k())
self.total_bond_to_staking_supply(params.staking_supply())
}
pub fn estimate_reward(
&self,
params: &RewardParams,
) -> Result<(u64, u64, u64), MixnetContractError> {
) -> Result<RewardEstimate, MixnetContractError> {
let total_node_reward = self
.reward(params)
.reward()
.checked_to_num::<u128>()
.unwrap_or_default();
let node_profit = self
.node_profit(params)
.checked_to_num::<u128>()
.unwrap_or_default();
let operator_cost = params
.node
.operator_cost()
.checked_to_num::<u128>()
.unwrap_or_default();
let operator_reward = self.operator_reward(params);
// Total reward has to be the sum of operator and delegator rewards
let delegators_reward = total_node_reward - operator_reward;
let delegators_reward = node_profit.saturating_sub(operator_reward);
Ok((
total_node_reward.try_into()?,
operator_reward.try_into()?,
delegators_reward.try_into()?,
))
Ok(RewardEstimate {
total_node_reward: total_node_reward.try_into()?,
operator_reward: operator_reward.try_into()?,
delegators_reward: delegators_reward.try_into()?,
node_profit: node_profit.try_into()?,
operator_cost: operator_cost.try_into()?,
})
}
// keybase://chat/nymtech#dev-core/14473
pub fn reward(&self, params: &RewardParams) -> NodeRewardResult {
let lambda = self.lambda(params);
let sigma = self.sigma(params);
let lambda_ticked = self.lambda_ticked(params);
let sigma_ticked = self.sigma_ticked(params);
let reward = params.performance()
* params.epoch_reward_pool()
* (sigma * params.omega()
+ params.alpha() * lambda * sigma * params.rewarded_set_size())
* (sigma_ticked * params.omega()
+ params.alpha() * lambda_ticked * sigma_ticked * params.rewarded_set_size())
/ (ONE + params.alpha());
// we only need regular lambda and sigma to calculate operator and delegator rewards
NodeRewardResult {
reward,
lambda,
sigma,
lambda: self.lambda(params),
sigma: self.sigma(params),
}
}
pub fn node_profit(&self, params: &RewardParams) -> U128 {
if self.reward(params).reward() < params.node.operator_cost() {
U128::from_num(0u128)
} else {
self.reward(params).reward() - params.node.operator_cost()
}
self.reward(params)
.reward()
.saturating_sub(params.node.operator_cost())
}
pub fn operator_reward(&self, params: &RewardParams) -> u128 {
@@ -474,11 +490,9 @@ impl MixNodeBond {
if reward.sigma == 0 {
return 0;
}
let profit = if reward.reward < params.node.operator_cost() {
U128::from_num(0u128)
} else {
reward.reward - params.node.operator_cost()
};
let profit = reward.reward.saturating_sub(params.node.operator_cost());
let operator_base_reward = reward.reward.min(params.node.operator_cost());
// Div by zero checked above
let operator_reward = (self.profit_margin()
@@ -500,9 +514,8 @@ impl MixNodeBond {
}
pub fn sigma_ratio(&self, params: &RewardParams) -> U128 {
if self.total_bond_to_circulating_supply(params.circulating_supply()) < params.one_over_k()
{
self.total_bond_to_circulating_supply(params.circulating_supply())
if self.total_bond_to_staking_supply(params.staking_supply()) < params.one_over_k() {
self.total_bond_to_staking_supply(params.staking_supply())
} else {
params.one_over_k()
}
@@ -99,6 +99,17 @@ pub enum ExecuteMsg {
},
// AdvanceCurrentInterval {},
AdvanceCurrentEpoch {},
ClaimOperatorReward {},
ClaimOperatorRewardOnBehalf {
owner: String,
},
ClaimDelegatorReward {
mix_identity: IdentityKey,
},
ClaimDelegatorRewardOnBehalf {
mix_identity: IdentityKey,
owner: String,
},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
@@ -42,7 +42,7 @@ impl NodeEpochRewards {
}
pub fn operator_cost(&self) -> U128 {
U128::from_num(self.params.uptime.u128() / 100u128 * DEFAULT_OPERATOR_INTERVAL_COST as u128)
self.params.operator_cost()
}
pub fn node_profit(&self) -> U128 {
@@ -78,9 +78,9 @@ impl NodeEpochRewards {
) -> Result<Uint128, MixnetContractError> {
// change all values into their fixed representations
let delegation_amount = U128::from_num(delegation_amount.u128());
let circulating_supply = U128::from_num(epoch_reward_params.circulating_supply());
let staking_supply = U128::from_num(epoch_reward_params.staking_supply());
let scaled_delegation_amount = delegation_amount / circulating_supply;
let scaled_delegation_amount = delegation_amount / staking_supply;
let check_div_by_zero =
if let Some(value) = scaled_delegation_amount.checked_div(self.sigma()) {
@@ -105,7 +105,8 @@ pub struct EpochRewardParams {
epoch_reward_pool: Uint128,
rewarded_set_size: Uint128,
active_set_size: Uint128,
circulating_supply: Uint128,
circulating_supply: Option<Uint128>,
staking_supply: Option<Uint128>,
sybil_resistance_percent: u8,
active_set_work_factor: u8,
}
@@ -115,7 +116,7 @@ impl EpochRewardParams {
epoch_reward_pool: u128,
rewarded_set_size: u128,
active_set_size: u128,
circulating_supply: u128,
staking_supply: u128,
sybil_resistance_percent: u8,
active_set_work_factor: u8,
) -> EpochRewardParams {
@@ -123,7 +124,8 @@ impl EpochRewardParams {
epoch_reward_pool: Uint128::new(epoch_reward_pool),
rewarded_set_size: Uint128::new(rewarded_set_size),
active_set_size: Uint128::new(active_set_size),
circulating_supply: Uint128::new(circulating_supply),
circulating_supply: None,
staking_supply: Some(Uint128::new(staking_supply)),
sybil_resistance_percent,
active_set_work_factor,
}
@@ -136,7 +138,8 @@ impl EpochRewardParams {
pub fn new_empty() -> Self {
EpochRewardParams {
epoch_reward_pool: Uint128::new(0),
circulating_supply: Uint128::new(0),
staking_supply: Some(Uint128::new(0)),
circulating_supply: None,
sybil_resistance_percent: 0,
rewarded_set_size: Uint128::new(0),
active_set_size: Uint128::new(0),
@@ -152,8 +155,14 @@ impl EpochRewardParams {
self.active_set_size.u128()
}
pub fn circulating_supply(&self) -> u128 {
self.circulating_supply.u128()
pub fn staking_supply(&self) -> u128 {
if let Some(s) = self.staking_supply {
s.u128()
} else if let Some(c) = self.circulating_supply {
c.u128()
} else {
0
}
}
pub fn epoch_reward_pool(&self) -> u128 {
@@ -178,11 +187,15 @@ impl NodeRewardParams {
}
pub fn operator_cost(&self) -> U128 {
U128::from_num(self.uptime.u128() / 100u128 * DEFAULT_OPERATOR_INTERVAL_COST as u128)
self.performance() * U128::from_num(DEFAULT_OPERATOR_INTERVAL_COST)
}
pub fn uptime(&self) -> u128 {
self.uptime.u128()
pub fn uptime(&self) -> Uint128 {
self.uptime
}
pub fn performance(&self) -> U128 {
U128::from_num(self.uptime.u128()) / U128::from_num(100)
}
pub fn set_reward_blockstamp(&mut self, blockstamp: u64) {
@@ -233,7 +246,7 @@ impl RewardParams {
}
pub fn performance(&self) -> U128 {
U128::from_num(self.node.uptime.u128()) / U128::from_num(100)
self.node.performance()
}
pub fn set_reward_blockstamp(&mut self, blockstamp: u64) {
@@ -248,16 +261,16 @@ impl RewardParams {
self.epoch.rewarded_set_size.u128()
}
pub fn circulating_supply(&self) -> u128 {
self.epoch.circulating_supply.u128()
pub fn staking_supply(&self) -> u128 {
self.epoch.staking_supply()
}
pub fn reward_blockstamp(&self) -> u64 {
self.node.reward_blockstamp
}
pub fn uptime(&self) -> u128 {
self.node.uptime.u128()
pub fn uptime(&self) -> Uint128 {
self.node.uptime()
}
pub fn one_over_k(&self) -> U128 {
@@ -43,6 +43,7 @@ pub struct ContractStateParams {
// subset of rewarded mixnodes that are actively receiving mix traffic
// used to handle shorter-term (e.g. hourly) fluctuations of demand
pub mixnode_active_set_size: u32,
pub staking_supply: Uint128,
}
impl Display for ContractStateParams {
@@ -0,0 +1,14 @@
[package]
name = "multisig-contract-common"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cw-utils = { version = "0.13.1" }
cw3 = { version = "0.13.1" }
cw4 = { version = "0.13.1" }
cosmwasm-std = "1.0.0"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
@@ -0,0 +1 @@
pub mod msg;
@@ -1,7 +1,11 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{CosmosMsg, Empty};
pub use cw3::ProposalResponse;
use cw3::Vote;
use cw4::MemberChangedHookMsg;
use cw_utils::{Duration, Expiration, Threshold};
@@ -6,12 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cosmwasm-std = "1.0.0-beta8"
cosmwasm-std = "1.0.0"
mixnet-contract-common = { path = "../mixnet-contract" }
serde = { version = "1.0", features = ["derive"] }
schemars = "0.8"
cw-storage-plus = "0.13.2"
cw-storage-plus = "0.13.4"
config = { path = "../../config" }
[dev-dependencies]
ts-rs = "6.1.2"
[features]
generate-ts = []
@@ -20,6 +20,7 @@ pub const VESTING_UPDATE_MIXNODE_CONFIG_EVENT_TYPE: &str = "vesting_update_mixno
pub const TRACK_MIXNODE_UNBOND_EVENT_TYPE: &str = "track_mixnode_unbond";
pub const TRACK_GATEWAY_UNBOND_EVENT_TYPE: &str = "track_gateway_unbond";
pub const TRACK_UNDELEGATION_EVENT_TYPE: &str = "track_undelegation";
pub const TRACK_REWARD_EVENT_TYPE: &str = "track_reaward";
// attributes that are used in multiple places
pub const OWNER_KEY: &str = "owner";
@@ -136,3 +137,7 @@ pub fn new_track_gateway_unbond_event() -> Event {
pub fn new_track_undelegation_event() -> Event {
Event::new(TRACK_UNDELEGATION_EVENT_TYPE)
}
pub fn new_track_reward_event() -> Event {
Event::new(TRACK_REWARD_EVENT_TYPE)
}
@@ -5,6 +5,8 @@ use cosmwasm_std::{Coin, Timestamp};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg};
pub mod events;
pub mod messages;
@@ -12,10 +14,10 @@ pub fn one_ucoin() -> Coin {
Coin::new(1, DENOM)
}
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
test,
ts(export, export_to = "../../../nym-wallet/src/types/rust/period.ts")
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Period.ts")
)]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, JsonSchema)]
pub enum Period {
@@ -49,6 +49,14 @@ impl VestingSpecification {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
TrackReward {
amount: Coin,
address: String,
},
ClaimOperatorReward {},
ClaimDelegatorReward {
mix_identity: String,
},
CompoundDelegatorReward {
mix_identity: String,
},
+2 -2
View File
@@ -12,9 +12,9 @@ nymcoconut = { path = "../nymcoconut" }
log = "0.4"
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]}
thiserror = "1.0"
tokio = { version = "1.4", features = [ "rt-multi-thread", "net", "signal", "fs" ] }
tokio = { version = "1.19.1", features = [ "rt-multi-thread", "net", "signal", "fs" ] }
[build-dependencies]
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { version = "1.4", features = ["rt-multi-thread", "macros"] }
tokio = { version = "1.19.1", features = ["rt-multi-thread", "macros"] }
+1 -1
View File
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
cosmrs = { version = "0.4.1", optional = true }
cosmrs = { version = "0.7.0", optional = true }
thiserror = "1.0"
url = "2.2"
+4 -1
View File
@@ -204,7 +204,10 @@ mod test {
.to_base58_string(),
)
.unwrap(),
encryption::KeyPair::new(&mut rng).private_key().clone(),
encryption::PrivateKey::from_bytes(
&encryption::KeyPair::new(&mut rng).private_key().to_bytes(),
)
.unwrap(),
);
assert!(!BandwidthVoucher::verify_against_plain(
&[],
+3 -16
View File
@@ -51,12 +51,7 @@ pub async fn obtain_aggregate_verification_key(
let mut shares = Vec::with_capacity(validators.len());
let mut client = validator_client::ApiClient::new(validators[0].clone());
let response = client.get_coconut_verification_key().await?;
indices.push(1);
shares.push(response.key);
for (id, validator_url) in validators.iter().enumerate().skip(1) {
for (id, validator_url) in validators.iter().enumerate() {
client.change_validator_api(validator_url.clone());
let response = client.get_coconut_verification_key().await?;
indices.push((id + 1) as u64);
@@ -135,14 +130,7 @@ pub async fn obtain_aggregate_signature(
let mut validators_partial_vks: Vec<VerificationKey> = Vec::with_capacity(validators.len());
let mut client = validator_client::ApiClient::new(validators[0].clone());
let validator_partial_vk = client.get_coconut_verification_key().await?;
validators_partial_vks.push(validator_partial_vk.key.clone());
let first =
obtain_partial_credential(params, attributes, &client, &validator_partial_vk.key).await?;
shares.push(SignatureShare::new(first, 1));
for (id, validator_url) in validators.iter().enumerate().skip(1) {
for (id, validator_url) in validators.iter().enumerate() {
client.change_validator_api(validator_url.clone());
let validator_partial_vk = client.get_coconut_verification_key().await?;
validators_partial_vks.push(validator_partial_vk.key.clone());
@@ -193,8 +181,7 @@ pub fn prepare_credential_for_spending(
Ok(Credential::new(
PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES,
theta,
voucher_value.to_string(),
voucher_value,
voucher_info,
signature,
))
}

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