Compare commits

..

77 Commits

Author SHA1 Message Date
Jędrzej Stuczyński 3e5923eaad merged with fbdf31b879 2022-06-10 09:56:35 +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
Jędrzej Stuczyński c5350f30aa Regenerated rust => ts types 2022-06-09 14:42:15 +01:00
Jon Häggblad e9aa75ccac wallet: fix clippy (#1334) 2022-06-09 14:35:44 +02:00
Jędrzej Stuczyński 7ffc8b9999 More type-restrictive exported denom type 2022-06-09 11:49:12 +01: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
Jędrzej Stuczyński 7c9fbc9c73 Fixed conversion to display coin 2022-06-07 10:11:04 +01: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
Jędrzej Stuczyński 2bcdc4c3d0 Removed explicit Arc and RwLock from all tauri commands 2022-06-06 17:51:45 +01:00
Jędrzej Stuczyński 8300daa117 Minor post-merge fixes 2022-06-06 17:31:09 +01:00
Jędrzej Stuczyński a60de5764d merge with wallet-delegation-ui-squashed 2022-06-06 17:18:48 +01:00
Jędrzej Stuczyński 23b093349d Fixed up tests and made clippy happier 2022-06-06 17:09:30 +01:00
Jędrzej Stuczyński 8955ee0b1d More unification for conversion methods 2022-06-06 16:43:12 +01:00
Jędrzej Stuczyński 9ef87df573 Display for Fee 2022-06-06 16:24:49 +01:00
Jędrzej Stuczyński ce7717fb2a Finished purge of MajorCurrencyAmount 2022-06-06 16:18:33 +01: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
Jędrzej Stuczyński 24c146766d Merge with wallet-claim-rewards 2022-06-06 12:04:15 +01:00
Jędrzej Stuczyński b6ddaebe67 Attempt at dec-coinifying get_all_mix_delegations 2022-06-06 11:59:02 +01:00
durch 282b18660f PR comments 2022-06-06 12:38:33 +02:00
Jędrzej Stuczyński b248f2e4b5 Further replacements of MajorCurrencyAmount into DecCoin 2022-06-06 10:33:41 +01:00
durch 184dd7767d Sort CHANGELOG lines 2022-06-06 11:28:36 +02:00
durch 2483a545b7 CHANGELOG 2022-06-06 11:27:09 +02:00
durch df1926071a Add claim and compound wallet endpoints, proc_macro to generate execute and simulate 2022-06-06 11:21:35 +02:00
Jędrzej Stuczyński 81a206f6c0 Further WIP work on transforming usages of MajorCurrencyAmount into DecCoin 2022-06-01 17:25:27 +01:00
Jędrzej Stuczyński 87e8666b86 'New' API on 'send' 2022-06-01 16:52:26 +01:00
fmtabbara 3519d0c31d Merge branch 'develop' into feature/wallet-delegation-ui-squashed 2022-06-01 16:32:34 +01:00
Jędrzej Stuczyński dbbd94d64c Generating typescript type for DecCoin 2022-06-01 16:21:17 +01:00
Jędrzej Stuczyński 93705d83ab Denom registration + conversion 2022-06-01 16:18:17 +01:00
Jędrzej Stuczyński 66b71fe87b No longer exposing plain 'DENOM' 2022-06-01 13:44:54 +01:00
Jędrzej Stuczyński 4f20085c05 Introduced concept of denom details 2022-06-01 13:32:38 +01:00
fmtabbara a33c21d438 Merge branch 'develop' into feature/wallet-delegation-ui-squashed 2022-06-01 11:23:05 +01:00
Jędrzej Stuczyński 04d02b08bc Merged with develop 2022-06-01 11:15:41 +01:00
Jędrzej Stuczyński 9460276131 Bunch of temporary workaround to have wallet working-ish 2022-06-01 10:59:41 +01:00
Jędrzej Stuczyński 84c9394eba Broken, but compilable first stage of post-merging 2022-06-01 09:57:40 +01:00
fmtabbara 6030d3831f refresh on network or client details change 2022-05-31 15:54:31 +01:00
Jędrzej Stuczyński 241f0cf93a changelog 2022-05-31 11:48:29 +01:00
Jędrzej Stuczyński 11122635f9 Refactored missed coin-generic API methods 2022-05-31 11:43:04 +01:00
Jędrzej Stuczyński ea54a3edc2 Merge with develop 2022-05-31 10:50:02 +01:00
Jędrzej Stuczyński 985a38429d Fixed up tests and clippy 2022-05-31 10:43:17 +01:00
fmtabbara c9f821864a only return events table if there are events 2022-05-31 10:06:29 +01:00
fmtabbara 37d55f3a06 handle undelegation of locked tokens 2022-05-30 22:07:05 +01:00
fmtabbara b2ce142c17 integrate modal divider with modal component 2022-05-30 22:06:23 +01:00
Jędrzej Stuczyński 374baa5ec1 Fixed validator api 2022-05-30 16:13:48 +01:00
Jędrzej Stuczyński de1df74eb5 Simplified the API by removing the generics in favour of explicit Coin type 2022-05-30 16:09:37 +01:00
Jędrzej Stuczyński 766c31544e Made wallet compilable with the recent changes 2022-05-30 15:58:31 +01:00
Jędrzej Stuczyński ecca7e8479 CoinConverter trait 2022-05-30 14:51:12 +01:00
Jędrzej Stuczyński 84a42f6ed9 Changed client API to use the new coin type 2022-05-30 14:46:05 +01: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 5925e85684 try_add 2022-05-30 11:37:18 +01:00
Jędrzej Stuczyński 972c60726c Additional From implementations plus a constructor 2022-05-30 11:31:58 +01:00
fmtabbara ece22b9703 spell delegations correctly! 2022-05-30 11:29:02 +01:00
Jędrzej Stuczyński 3f718feb41 Created nymd internal coin 2022-05-30 11:22:44 +01:00
fmtabbara b550c32db6 update wording 2022-05-30 11:20:11 +01:00
fmtabbara 83090c0a25 use token pool selector 2022-05-30 11:16:52 +01:00
fmtabbara 97ad1a2e46 fix duplicate key 2022-05-30 11:16:19 +01:00
fmtabbara 9fbefa34e8 get wallet balance after transactions 2022-05-30 09:06:16 +01:00
Mark Sinclair 0812296399 Integrate fees changes:
- make operations available as requests (typed with any for now, needs changing)
- move `FeeDetails` to `common/types`
- mock `getGasFee()`
2022-05-27 18:33:02 +01:00
Mark Sinclair 51b04081a3 Fix rebase errors 2022-05-27 17:44:52 +01:00
tommy 7f2027ca6b 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
2022-05-27 16:50:16 +01:00
gala1234 e7a8221005 Merge branch 'develop' into feature-219-explorer-small-changes 2022-05-26 12:05:28 +02:00
gala1234 1ee1d4ebf7 explorer: altering api response to make ui work 2022-05-26 11:32:57 +02: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
388 changed files with 12835 additions and 3284 deletions
+10 -1
View File
@@ -1,5 +1,7 @@
# 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
@@ -9,7 +11,6 @@
- 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`.
- 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]).
- 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]).
@@ -20,6 +21,7 @@
- wallet: compound and claim reward endpoints for operators and delegators ([#1302])
- wallet: require password to switch accounts
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- network-statistics: a new mixnet service that aggregates and exposes anonymized data about mixnet services ([#1328])
### Fixed
@@ -29,11 +31,15 @@
- 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])
### 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])
[#1249]: https://github.com/nymtech/nym/pull/1249
[#1256]: https://github.com/nymtech/nym/pull/1256
@@ -49,6 +55,9 @@
[#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
[#1328]: https://github.com/nymtech/nym/pull/1328
## [nym-wallet-v1.0.4](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.4) (2022-05-04)
Generated
+149 -118
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",
@@ -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"
@@ -778,10 +772,10 @@ checksum = "8413275b23cb5a0734d9d1e3e33f0b5b94547c1e94776dbc3149dbf46588a533"
dependencies = [
"bip32",
"cosmos-sdk-proto",
"ecdsa 0.13.4",
"ecdsa",
"eyre",
"getrandom 0.2.6",
"k256 0.10.4",
"k256",
"prost 0.10.3",
"prost-types 0.10.1",
"rand_core 0.6.3",
@@ -795,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",
@@ -1037,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"
@@ -1156,9 +1138,9 @@ dependencies = [
[[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",
@@ -1246,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]]
@@ -1404,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",
]
@@ -1474,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"
@@ -1497,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",
@@ -2641,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"
@@ -2660,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",
@@ -3181,6 +3114,7 @@ dependencies = [
"rocket",
"serde",
"serial_test",
"task",
"tokio",
"tokio-util 0.7.3",
"toml",
@@ -3195,7 +3129,6 @@ dependencies = [
name = "nym-network-requester"
version = "1.0.1"
dependencies = [
"bincode",
"clap 2.34.0",
"dirs",
"futures",
@@ -3209,16 +3142,32 @@ dependencies = [
"publicsuffix",
"rand 0.7.3",
"reqwest",
"rocket",
"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"
@@ -3255,6 +3204,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"
@@ -3302,6 +3277,7 @@ dependencies = [
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-api-requests",
"validator-client",
@@ -3309,6 +3285,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"
@@ -3812,24 +3806,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",
]
@@ -4454,7 +4438,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",
]
@@ -4787,9 +4771,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",
]
@@ -4891,9 +4875,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",
]
@@ -5240,15 +5224,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"
@@ -5256,7 +5231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27"
dependencies = [
"base64ct",
"der 0.5.1",
"der",
]
[[package]]
@@ -5388,6 +5363,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"
@@ -5459,6 +5444,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"
@@ -5509,6 +5516,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"
@@ -5535,7 +5551,7 @@ dependencies = [
"ed25519-dalek",
"flex-error",
"futures",
"k256 0.10.4",
"k256",
"num-traits",
"once_cell",
"prost 0.10.3",
@@ -6076,6 +6092,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"
+6 -1
View File
@@ -53,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 = [
@@ -76,4 +81,4 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly"]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly", "nym-wallet"]
+4
View File
@@ -54,3 +54,7 @@ fmt-wallet:
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
+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

+2 -2
View File
@@ -8,7 +8,7 @@ use url::Url;
use crate::error::Result;
use crate::{MNEMONIC, NYMD_URL};
use network_defaults::{DEFAULT_NETWORK, DENOM, VOUCHER_INFO};
use network_defaults::{DEFAULT_NETWORK, MIX_DENOM, VOUCHER_INFO};
use validator_client::nymd::traits::CoconutBandwidthSigningClient;
use validator_client::nymd::{Coin, Fee, NymdClient, SigningNymdClient};
@@ -34,7 +34,7 @@ impl Client {
encryption_key: String,
fee: Option<Fee>,
) -> Result<String> {
let amount = Coin::new(amount as u128, DENOM.to_string());
let amount = Coin::new(amount as u128, MIX_DENOM.base.to_string());
Ok(self
.nymd_client
.deposit(
+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();
}
+3
View File
@@ -187,6 +187,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 {
-4
View File
@@ -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
@@ -83,7 +83,7 @@ impl GatewayClient {
) -> Self {
GatewayClient {
authenticated: false,
disabled_credentials_mode: false,
disabled_credentials_mode: true,
bandwidth_remaining: 0,
gateway_address,
gateway_identity,
@@ -100,8 +100,8 @@ impl GatewayClient {
}
}
pub fn set_disabled_credentials_mode(&mut self, _disabled_credentials_mode: bool) {
self.disabled_credentials_mode = false;
pub fn set_disabled_credentials_mode(&mut self, disabled_credentials_mode: bool) {
self.disabled_credentials_mode = disabled_credentials_mode;
}
// TODO: later convert into proper builder methods
@@ -40,10 +40,9 @@ 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"
[features]
@@ -58,3 +57,5 @@ nymd-client = [
"itertools",
"cosmwasm-std",
]
generate-ts = []
@@ -26,7 +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 as CosmosCoin, Denom, Tx};
use cosmrs::{tx, AccountId, Coin as CosmosCoin, Tx};
use prost::Message;
use serde::{Deserialize, Serialize};
use std::convert::{TryFrom, TryInto};
@@ -121,7 +121,7 @@ pub trait CosmWasmClient: rpc::Client {
async fn get_balance(
&self,
address: &AccountId,
search_denom: Denom,
search_denom: String,
) -> Result<Option<Coin>, NymdError> {
let path = Some("/cosmos.bank.v1beta1.Query/Balance".parse().unwrap());
@@ -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
@@ -1,8 +1,10 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::Coin;
use cosmrs::tx;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
pub mod gas_price;
@@ -14,6 +16,40 @@ pub enum Fee {
Auto(Option<f32>),
}
impl Display for Fee {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Fee::Manual(fee) => {
write!(f, "Fee in manual mode with ")?;
for fee in &fee.amount {
write!(f, "{}{} paid in fees, ", fee.amount, fee.denom)?;
}
write!(f, "{} set as gas limit, ", fee.gas_limit)?;
if let Some(payer) = &fee.payer {
write!(f, "{payer} set as payer, ")?;
}
if let Some(granter) = &fee.granter {
write!(f, "{granter} set as granter")?;
}
Ok(())
}
Fee::Auto(Some(multiplier)) => {
write!(f, "Fee in auto mode with {multiplier} simulated multiplier")
}
Fee::Auto(None) => write!(f, "Fee in auto mode with no custom simulated multiplier"),
}
}
}
impl Fee {
pub fn try_get_manual_amount(&self) -> Option<Vec<Coin>> {
match self {
Fee::Manual(tx_fee) => Some(tx_fee.amount.iter().cloned().map(Into::into).collect()),
Fee::Auto(_) => None,
}
}
}
impl From<tx::Fee> for Fee {
fn from(fee: tx::Fee) -> Self {
Fee::Manual(fee)
@@ -134,7 +134,7 @@ impl NymdClient<SigningNymdClient> {
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
let denom = network.denom();
let denom = network.mix_denom().base;
let client_address = signer
.try_derive_accounts()?
.into_iter()
@@ -176,7 +176,7 @@ impl NymdClient<SigningNymdClient> {
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
let prefix = network.bech32_prefix();
let denom = network.denom();
let denom = network.mix_denom().base;
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic)?;
let client_address = wallet
.try_derive_accounts()?
@@ -189,23 +189,23 @@ impl NymdClient<SigningNymdClient> {
client: SigningNymdClient::connect_with_signer(endpoint, wallet, gas_price)?,
client_address: Some(client_address),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
mixnet_contract_address: DEFAULT_NETWORK
mixnet_contract_address: network
.mixnet_contract_address()
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: DEFAULT_NETWORK
vesting_contract_address: network
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: DEFAULT_NETWORK
bandwidth_claim_contract_address: network
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
coconut_bandwidth_contract_address: DEFAULT_NETWORK
coconut_bandwidth_contract_address: network
.coconut_bandwidth_contract_address()
.parse()
.unwrap(),
multisig_contract_address: DEFAULT_NETWORK.multisig_contract_address().parse().unwrap(),
multisig_contract_address: network.multisig_contract_address().parse().unwrap(),
})
}
}
@@ -289,7 +289,17 @@ impl<C> NymdClient<C> {
where
C: CosmWasmClient + Sync,
{
Ok(self.client.get_block(None).await?.block.header.time)
self.get_block_timestamp(None).await
}
pub async fn get_block_timestamp(
&self,
height: Option<u32>,
) -> Result<TendermintTime, NymdError>
where
C: CosmWasmClient + Sync,
{
Ok(self.client.get_block(height).await?.block.header.time)
}
pub async fn get_current_block_height(&self) -> Result<Height, NymdError>
@@ -328,7 +338,7 @@ impl<C> NymdClient<C> {
pub async fn get_balance(
&self,
address: &AccountId,
denom: Denom,
denom: String,
) -> Result<Option<Coin>, NymdError>
where
C: CosmWasmClient + Sync,
@@ -49,7 +49,7 @@ impl<C: SigningCosmWasmClient + Sync + Send> MultisigSigningClient for NymdClien
) -> 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()),
funds: Coin::new(voucher_value, DEFAULT_NETWORK.mix_denom().base),
};
let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: self.coconut_bandwidth_contract_address().to_string(),
@@ -183,6 +183,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
.map(Into::into)
}
/// Returns the total amount of delegated tokens that have vested
async fn delegated_vesting(
&self,
vesting_account_address: &str,
-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 = []
@@ -33,7 +33,7 @@ pub struct Delegation {
pub node_identity: IdentityKey,
pub amount: Coin,
pub block_height: u64,
pub proxy: Option<Addr>, // proxy address used to delegate the funds on behalf of anouther address
pub proxy: Option<Addr>, // proxy address used to delegate the funds on behalf of another address
}
impl Eq for Delegation {}
@@ -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 {
@@ -40,6 +37,16 @@ pub enum DelegationEvent {
Undelegate(PendingUndelegate),
}
impl DelegationEvent {
pub fn delegation_amount(&self) -> Option<Coin> {
match self {
DelegationEvent::Delegate(delegation) => Some(delegation.amount.clone()),
// I think it would be nice to also expose an amount here to know how much we're undelegating
DelegationEvent::Undelegate(_) => None,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct PendingUndelegate {
mix_identity: IdentityKey,
@@ -109,11 +116,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,
@@ -9,6 +9,6 @@ edition = "2021"
cw-utils = { version = "0.13.1" }
cw3 = { version = "0.13.1" }
cw4 = { version = "0.13.1" }
cosmwasm-std = "1.0.0-beta6"
cosmwasm-std = "1.0.0"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
@@ -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 = []
@@ -1,6 +1,6 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{Coin, Timestamp};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -11,13 +11,13 @@ pub mod events;
pub mod messages;
pub fn one_ucoin() -> Coin {
Coin::new(1, DENOM)
Coin::new(1, MIX_DENOM.base)
}
#[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 {
@@ -28,8 +28,8 @@ pub enum Period {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct PledgeData {
amount: Coin,
block_time: Timestamp,
pub amount: Coin,
pub block_time: Timestamp,
}
impl PledgeData {
@@ -48,9 +48,9 @@ impl PledgeData {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct OriginalVestingResponse {
amount: Coin,
number_of_periods: usize,
period_duration: u64,
pub amount: Coin,
pub number_of_periods: usize,
pub period_duration: u64,
}
impl OriginalVestingResponse {
+22 -9
View File
@@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt, str::FromStr};
use crate::{
DefaultNetworkDetails, ValidatorDetails, MAINNET_DEFAULTS, QA_DEFAULTS, SANDBOX_DEFAULTS,
DefaultNetworkDetails, DenomDetails, DenomDetailsOwned, ValidatorDetails, MAINNET_DEFAULTS,
QA_DEFAULTS, SANDBOX_DEFAULTS,
};
use thiserror::Error;
@@ -24,7 +25,7 @@ pub enum Network {
}
impl Network {
fn details(&self) -> &DefaultNetworkDetails<'_> {
fn details(&self) -> &DefaultNetworkDetails {
match self {
Self::QA => &QA_DEFAULTS,
Self::SANDBOX => &SANDBOX_DEFAULTS,
@@ -36,8 +37,12 @@ impl Network {
self.details().bech32_prefix
}
pub fn denom(&self) -> &str {
self.details().denom
pub fn mix_denom(&self) -> &DenomDetails {
&self.details().mix_denom
}
pub fn stake_denom(&self) -> &DenomDetails {
&self.details().stake_denom
}
pub fn mixnet_contract_address(&self) -> &str {
@@ -97,18 +102,20 @@ impl fmt::Display for Network {
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct NetworkDetails {
bech32_prefix: String,
denom: String,
mix_denom: DenomDetailsOwned,
stake_denom: DenomDetailsOwned,
mixnet_contract_address: String,
vesting_contract_address: String,
bandwidth_claim_contract_address: String,
validators: Vec<ValidatorDetails>,
}
impl From<&DefaultNetworkDetails<'_>> for NetworkDetails {
fn from(details: &DefaultNetworkDetails<'_>) -> Self {
impl From<&DefaultNetworkDetails> for NetworkDetails {
fn from(details: &DefaultNetworkDetails) -> Self {
NetworkDetails {
bech32_prefix: details.bech32_prefix.into(),
denom: details.denom.into(),
mix_denom: details.mix_denom.into(),
stake_denom: details.stake_denom.into(),
mixnet_contract_address: details.mixnet_contract_address.into(),
vesting_contract_address: details.vesting_contract_address.into(),
bandwidth_claim_contract_address: details.bandwidth_claim_contract_address.into(),
@@ -117,6 +124,12 @@ impl From<&DefaultNetworkDetails<'_>> for NetworkDetails {
}
}
impl NetworkDetails {
pub fn base_mix_denom(&self) -> &str {
&self.mix_denom.base
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
pub struct SupportedNetworks {
networks: HashMap<Network, NetworkDetails>,
@@ -141,7 +154,7 @@ impl SupportedNetworks {
pub fn denom(&self, network: Network) -> Option<&str> {
self.networks
.get(&network)
.map(|network_details| network_details.denom.as_str())
.map(|network_details| network_details.base_mix_denom())
}
pub fn mixnet_contract_address(&self, network: Network) -> Option<&str> {
+79 -41
View File
@@ -17,24 +17,24 @@ pub mod sandbox;
cfg_if::cfg_if! {
if #[cfg(network = "mainnet")] {
pub const DEFAULT_NETWORK: all::Network = all::Network::MAINNET;
pub const DENOM: &str = mainnet::DENOM;
pub const STAKE_DENOM: &str = mainnet::STAKE_DENOM;
pub const MIX_DENOM: DenomDetails = mainnet::MIX_DENOM;
pub const STAKE_DENOM: DenomDetails = mainnet::STAKE_DENOM;
pub const ETH_CONTRACT_ADDRESS: [u8; 20] = mainnet::_ETH_CONTRACT_ADDRESS;
pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = mainnet::_ETH_ERC20_CONTRACT_ADDRESS;
} else if #[cfg(network = "qa")] {
pub const DEFAULT_NETWORK: all::Network = all::Network::QA;
pub const DENOM: &str = qa::DENOM;
pub const STAKE_DENOM: &str = qa::STAKE_DENOM;
pub const MIX_DENOM: DenomDetails = qa::MIX_DENOM;
pub const STAKE_DENOM: DenomDetails = qa::STAKE_DENOM;
pub const ETH_CONTRACT_ADDRESS: [u8; 20] = qa::_ETH_CONTRACT_ADDRESS;
pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = qa::_ETH_ERC20_CONTRACT_ADDRESS;
} else if #[cfg(network = "sandbox")] {
pub const DEFAULT_NETWORK: all::Network = all::Network::SANDBOX;
pub const DENOM: &str = sandbox::DENOM;
pub const STAKE_DENOM: &str = sandbox::STAKE_DENOM;
pub const MIX_DENOM: DenomDetails = sandbox::MIX_DENOM;
pub const STAKE_DENOM: DenomDetails = sandbox::STAKE_DENOM;
pub const ETH_CONTRACT_ADDRESS: [u8; 20] = sandbox::_ETH_CONTRACT_ADDRESS;
pub const ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = sandbox::_ETH_ERC20_CONTRACT_ADDRESS;
@@ -45,47 +45,49 @@ cfg_if::cfg_if! {
// future. If we do this, and also get rid of the references we could potentially unify with
// `NetworkDetails`.
#[derive(Debug)]
pub struct DefaultNetworkDetails<'a> {
bech32_prefix: &'a str,
denom: &'a str,
mixnet_contract_address: &'a str,
vesting_contract_address: &'a str,
bandwidth_claim_contract_address: &'a str,
coconut_bandwidth_contract_address: &'a str,
multisig_contract_address: &'a str,
rewarding_validator_address: &'a str,
pub struct DefaultNetworkDetails {
bech32_prefix: &'static str,
mix_denom: DenomDetails,
stake_denom: DenomDetails,
mixnet_contract_address: &'static str,
vesting_contract_address: &'static str,
bandwidth_claim_contract_address: &'static str,
coconut_bandwidth_contract_address: &'static str,
multisig_contract_address: &'static str,
rewarding_validator_address: &'static str,
validators: Vec<ValidatorDetails>,
}
static MAINNET_DEFAULTS: Lazy<DefaultNetworkDetails<'static>> =
Lazy::new(|| DefaultNetworkDetails {
bech32_prefix: mainnet::BECH32_PREFIX,
denom: mainnet::DENOM,
mixnet_contract_address: mainnet::MIXNET_CONTRACT_ADDRESS,
vesting_contract_address: mainnet::VESTING_CONTRACT_ADDRESS,
bandwidth_claim_contract_address: mainnet::BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
coconut_bandwidth_contract_address: mainnet::COCONUT_BANDWIDTH_CONTRACT_ADDRESS,
multisig_contract_address: mainnet::MULTISIG_CONTRACT_ADDRESS,
rewarding_validator_address: mainnet::REWARDING_VALIDATOR_ADDRESS,
validators: mainnet::validators(),
});
static MAINNET_DEFAULTS: Lazy<DefaultNetworkDetails> = Lazy::new(|| DefaultNetworkDetails {
bech32_prefix: mainnet::BECH32_PREFIX,
mix_denom: mainnet::MIX_DENOM,
stake_denom: mainnet::STAKE_DENOM,
mixnet_contract_address: mainnet::MIXNET_CONTRACT_ADDRESS,
vesting_contract_address: mainnet::VESTING_CONTRACT_ADDRESS,
bandwidth_claim_contract_address: mainnet::BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
coconut_bandwidth_contract_address: mainnet::COCONUT_BANDWIDTH_CONTRACT_ADDRESS,
multisig_contract_address: mainnet::MULTISIG_CONTRACT_ADDRESS,
rewarding_validator_address: mainnet::REWARDING_VALIDATOR_ADDRESS,
validators: mainnet::validators(),
});
static SANDBOX_DEFAULTS: Lazy<DefaultNetworkDetails<'static>> =
Lazy::new(|| DefaultNetworkDetails {
bech32_prefix: sandbox::BECH32_PREFIX,
denom: sandbox::DENOM,
mixnet_contract_address: sandbox::MIXNET_CONTRACT_ADDRESS,
vesting_contract_address: sandbox::VESTING_CONTRACT_ADDRESS,
bandwidth_claim_contract_address: sandbox::BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
coconut_bandwidth_contract_address: sandbox::COCONUT_BANDWIDTH_CONTRACT_ADDRESS,
multisig_contract_address: sandbox::MULTISIG_CONTRACT_ADDRESS,
rewarding_validator_address: sandbox::REWARDING_VALIDATOR_ADDRESS,
validators: sandbox::validators(),
});
static SANDBOX_DEFAULTS: Lazy<DefaultNetworkDetails> = Lazy::new(|| DefaultNetworkDetails {
bech32_prefix: sandbox::BECH32_PREFIX,
mix_denom: sandbox::MIX_DENOM,
stake_denom: sandbox::STAKE_DENOM,
mixnet_contract_address: sandbox::MIXNET_CONTRACT_ADDRESS,
vesting_contract_address: sandbox::VESTING_CONTRACT_ADDRESS,
bandwidth_claim_contract_address: sandbox::BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
coconut_bandwidth_contract_address: sandbox::COCONUT_BANDWIDTH_CONTRACT_ADDRESS,
multisig_contract_address: sandbox::MULTISIG_CONTRACT_ADDRESS,
rewarding_validator_address: sandbox::REWARDING_VALIDATOR_ADDRESS,
validators: sandbox::validators(),
});
static QA_DEFAULTS: Lazy<DefaultNetworkDetails<'static>> = Lazy::new(|| DefaultNetworkDetails {
static QA_DEFAULTS: Lazy<DefaultNetworkDetails> = Lazy::new(|| DefaultNetworkDetails {
bech32_prefix: qa::BECH32_PREFIX,
denom: qa::DENOM,
mix_denom: qa::MIX_DENOM,
stake_denom: qa::STAKE_DENOM,
mixnet_contract_address: qa::MIXNET_CONTRACT_ADDRESS,
vesting_contract_address: qa::VESTING_CONTRACT_ADDRESS,
bandwidth_claim_contract_address: qa::BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
@@ -95,6 +97,42 @@ static QA_DEFAULTS: Lazy<DefaultNetworkDetails<'static>> = Lazy::new(|| DefaultN
validators: qa::validators(),
});
#[derive(Debug, Copy, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct DenomDetails {
pub base: &'static str,
pub display: &'static str,
// i.e. display_amount * 10^display_exponent = base_amount
pub display_exponent: u32,
}
impl DenomDetails {
pub const fn new(base: &'static str, display: &'static str, display_exponent: u32) -> Self {
DenomDetails {
base,
display,
display_exponent,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct DenomDetailsOwned {
pub base: String,
pub display: String,
// i.e. display_amount * 10^display_exponent = base_amount
pub display_exponent: u32,
}
impl From<DenomDetails> for DenomDetailsOwned {
fn from(details: DenomDetails) -> Self {
DenomDetailsOwned {
base: details.base.to_owned(),
display: details.display.to_owned(),
display_exponent: details.display_exponent,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct ValidatorDetails {
// it is assumed those values are always valid since they're being provided in our defaults file
+4 -2
View File
@@ -1,11 +1,13 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ValidatorDetails;
use crate::{DenomDetails, ValidatorDetails};
pub(crate) const BECH32_PREFIX: &str = "n";
pub const DENOM: &str = "unym";
pub const STAKE_DENOM: &str = "unyx";
pub const MIX_DENOM: DenomDetails = DenomDetails::new("unym", "nym", 6);
pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6);
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
"n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g";
+4 -2
View File
@@ -1,11 +1,13 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ValidatorDetails;
use crate::{DenomDetails, ValidatorDetails};
pub(crate) const BECH32_PREFIX: &str = "n";
pub const DENOM: &str = "unym";
pub const STAKE_DENOM: &str = "unyx";
pub const MIX_DENOM: DenomDetails = DenomDetails::new("unym", "nym", 6);
pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6);
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
"n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep";
+4 -2
View File
@@ -1,11 +1,13 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ValidatorDetails;
use crate::{DenomDetails, ValidatorDetails};
pub(crate) const BECH32_PREFIX: &str = "nymt";
pub const DENOM: &str = "unymt";
pub const STAKE_DENOM: &str = "unyxt";
pub const MIX_DENOM: DenomDetails = DenomDetails::new("unymt", "nymt", 6);
pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyxt", "nyxt", 6);
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = "nymt1ghd753shjuwexxywmgs4xz7x2q732vcnstz02j";
pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "nymt14ejqjyq8um4p3xfqj74yld5waqljf88fn549lh";
+20
View File
@@ -32,6 +32,26 @@ impl Message {
const REQUEST_FLAG: u8 = 0;
const RESPONSE_FLAG: u8 = 1;
pub fn conn_id(&self) -> u64 {
match self {
Message::Request(req) => match req {
Request::Connect(c) => c.conn_id,
Request::Send(conn_id, _, _) => *conn_id,
},
Message::Response(resp) => resp.connection_id,
}
}
pub fn size(&self) -> usize {
match self {
Message::Request(req) => match req {
Request::Connect(_) => 0,
Request::Send(_, data, _) => data.len(),
},
Message::Response(resp) => resp.data.len(),
}
}
pub fn try_from_bytes(b: &[u8]) -> Result<Message, MessageError> {
if b.is_empty() {
return Err(MessageError::NoData);
+15
View File
@@ -0,0 +1,15 @@
# Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
# SPDX-License-Identifier: Apache-2.0
[package]
name = "statistics"
version = "1.0.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = "0.11"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
thiserror = "1"
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::StatsError;
use crate::StatsMessage;
pub const DEFAULT_STATISTICS_SERVICE_ADDRESS: &str = "127.0.0.1";
pub const DEFAULT_STATISTICS_SERVICE_PORT: u16 = 8090;
pub const STATISTICS_SERVICE_VERSION: &str = "/v1";
pub const STATISTICS_SERVICE_API_STATISTICS: &str = "statistic";
pub fn build_statistics_request_bytes(msg: StatsMessage) -> Result<Vec<u8>, StatsError> {
let json_msg = msg.to_json()?;
let req = reqwest::Request::new(
reqwest::Method::POST,
reqwest::Url::parse(&format!(
"http://{}:{}/{}/{}",
DEFAULT_STATISTICS_SERVICE_ADDRESS,
DEFAULT_STATISTICS_SERVICE_PORT,
STATISTICS_SERVICE_VERSION,
STATISTICS_SERVICE_API_STATISTICS
))
.unwrap(),
);
let data = format!(
"{} {} {:?}\n\
Content-Type: application/json\n\
Content-Length: {}\n\n\
{}\n",
req.method().as_str(),
req.url().as_str(),
req.version(),
json_msg.len(),
json_msg
);
Ok(data.into_bytes())
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StatsError {
#[error("Serde JSON error: {0}")]
SerdeJsonError(#[from] serde_json::Error),
}
+43
View File
@@ -0,0 +1,43 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use error::StatsError;
pub mod api;
pub mod error;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsMessage {
pub stats_data: Vec<StatsServiceData>,
pub interval_seconds: u32,
pub timestamp: String,
}
impl StatsMessage {
pub fn to_json(&self) -> Result<String, StatsError> {
Ok(serde_json::to_string(self)?)
}
pub fn from_json(s: &str) -> Result<Self, StatsError> {
Ok(serde_json::from_str(s)?)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsServiceData {
pub requested_service: String,
pub request_bytes: u32,
pub response_bytes: u32,
}
impl StatsServiceData {
pub fn new(requested_service: String, request_bytes: u32, response_bytes: u32) -> Self {
StatsServiceData {
requested_service,
request_bytes,
response_bytes,
}
}
}
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "task"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal"] }
tokio-util = { version = "0.7.3", features = ["codec"] }
[dev-dependencies]
tokio = { version = "1.19.1", features = ["rt-multi-thread", "net", "signal", "test-util", "macros"] }
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod shutdown;
pub use shutdown::{ShutdownListener, ShutdownNotifier};
+106
View File
@@ -0,0 +1,106 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::time::Duration;
use tokio::sync::watch::{self, error::SendError};
const SHUTDOWN_TIMER_SECS: u64 = 5;
/// Used to notify other tasks to gracefully shutdown
#[derive(Debug)]
pub struct ShutdownNotifier {
notify_tx: watch::Sender<()>,
notify_rx: Option<watch::Receiver<()>>,
}
impl Default for ShutdownNotifier {
fn default() -> Self {
let (notify_tx, notify_rx) = watch::channel(());
Self {
notify_tx,
notify_rx: Some(notify_rx),
}
}
}
impl ShutdownNotifier {
pub fn subscribe(&self) -> ShutdownListener {
ShutdownListener::new(
self.notify_rx
.as_ref()
.expect("Unable to subscribe to shutdown notifier that is already shutdown")
.clone(),
)
}
pub fn signal_shutdown(&self) -> Result<(), SendError<()>> {
self.notify_tx.send(())
}
pub async fn wait_for_shutdown(&mut self) {
if let Some(notify_rx) = self.notify_rx.take() {
drop(notify_rx);
}
tokio::select! {
_ = self.notify_tx.closed() => {
log::info!("All registered tasks succesfully shutdown");
},
_ = tokio::signal::ctrl_c() => {
log::info!("Forcing shutdown");
}
_ = tokio::time::sleep(Duration::from_secs(SHUTDOWN_TIMER_SECS)) => {
log::info!("Timout reached, forcing shutdown");
},
}
}
}
/// Listen for shutdown notifications
#[derive(Clone, Debug)]
pub struct ShutdownListener {
shutdown: bool,
notify: watch::Receiver<()>,
}
impl ShutdownListener {
pub fn new(notify: watch::Receiver<()>) -> ShutdownListener {
ShutdownListener {
shutdown: false,
notify,
}
}
pub fn is_shutdown(&self) -> bool {
self.shutdown
}
pub async fn recv(&mut self) {
if self.shutdown {
return;
}
let _ = self.notify.changed().await;
self.shutdown = true;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn signal_shutdown() {
let shutdown = ShutdownNotifier::default();
let mut listener = shutdown.subscribe();
let task = tokio::spawn(async move {
tokio::select! {
_ = listener.recv() => 42,
}
});
shutdown.signal_shutdown().unwrap();
assert_eq!(task.await.unwrap(), 42);
}
}
+10
View File
@@ -93,6 +93,16 @@ impl Node {
}
}
impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Node(id: {}, owner: {}, stake: {}, location: {}, host: {})",
self.identity_key, self.owner, self.stake, self.location, self.host,
)
}
}
impl filter::Versioned for Node {
fn version(&self) -> String {
self.version.clone()
+40
View File
@@ -0,0 +1,40 @@
[package]
name = "nym-types"
version = "1.0.0"
description = "Nym common types"
authors = ["Nym Technologies SA"]
edition = "2021"
rust-version = "1.58"
[dependencies]
eyre = "0.6.5"
log = "0.4"
itertools = "0.10"
reqwest = "0.11.9"
schemars = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
strum = { version = "0.23", features = ["derive"] }
thiserror = "1.0"
url = "2.2"
ts-rs = "6.1.2"
cosmwasm-std = "1.0.0-beta8"
cosmrs = "0.7.0"
validator-client = { path = "../../common/client-libs/validator-client", features = [
"nymd-client",
] }
mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" }
vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" }
config = { path = "../../common/config" }
coconut-interface = { path = "../../common/coconut-interface" }
# Used for Type conversion, can be extracted but its a lot of work
vesting-contract = { path = "../../contracts/vesting" }
[dev-dependencies]
tempfile = "3.3.0"
[features]
default = []
generate-ts = []
+70
View File
@@ -0,0 +1,70 @@
use crate::currency::{DecCoin, Denom};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Account.ts")
)]
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct Account {
// TODO: discuss with @MS whether it makes sense:
// 1. why are we restricting to single denom here? What if user holds both stake and mix currencies?
// 2. what's the `contract_address`? is it mixnet? vesting? coconut? why does it relate to an account anyway?
pub contract_address: String,
pub client_address: String,
pub denom: Denom,
}
impl Account {
pub fn new(contract_address: String, client_address: String, denom: Denom) -> Self {
Account {
contract_address,
client_address,
denom,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/AccountWithMnemonic.ts")
)]
#[derive(Serialize, Deserialize)]
pub struct AccountWithMnemonic {
pub account: Account,
pub mnemonic: String,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/AccountEntry.ts")
)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountEntry {
pub id: String,
pub address: String,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Balance.ts")
)]
#[derive(Serialize, Deserialize)]
pub struct Balance {
pub amount: DecCoin,
pub printable_balance: String,
}
impl Balance {
pub fn new(amount: DecCoin) -> Self {
Balance {
printable_balance: amount.to_string(),
amount,
}
}
}
+504
View File
@@ -0,0 +1,504 @@
use crate::error::TypesError;
use config::defaults::all::Network;
use config::defaults::DenomDetails;
use cosmwasm_std::Fraction;
use cosmwasm_std::{Decimal, Uint128};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt::{Display, Formatter};
use strum::{Display, EnumString, EnumVariantNames};
use validator_client::nymd::Coin;
#[cfg(feature = "generate-ts")]
use ts_rs::{Dependency, TS};
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/CurrencyDenom.ts")
)]
#[cfg_attr(feature = "generate-ts", ts(rename_all = "lowercase"))]
#[derive(
Display,
Serialize,
Deserialize,
Clone,
Debug,
EnumString,
EnumVariantNames,
PartialEq,
JsonSchema,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum CurrencyDenom {
#[strum(ascii_case_insensitive)]
Nym,
#[strum(ascii_case_insensitive)]
Nymt,
#[strum(ascii_case_insensitive)]
Nyx,
#[strum(ascii_case_insensitive)]
Nyxt,
}
pub type Denom = String;
#[derive(Debug, Default)]
pub struct RegisteredCoins(HashMap<Denom, CoinMetadata>);
impl RegisteredCoins {
pub fn default_denoms(network: Network) -> Self {
let mut network_coins = HashMap::new();
network_coins.insert(
network.mix_denom().base.into(),
(*network.mix_denom()).into(),
);
network_coins.insert(
network.stake_denom().base.into(),
(*network.stake_denom()).into(),
);
RegisteredCoins(network_coins)
}
pub fn insert(&mut self, denom: Denom, metadata: CoinMetadata) -> Option<CoinMetadata> {
self.0.insert(denom, metadata)
}
pub fn remove(&mut self, denom: &Denom) -> Option<CoinMetadata> {
self.0.remove(denom)
}
pub fn attempt_convert_to_base_coin(&self, coin: DecCoin) -> Result<Coin, TypesError> {
// check if this is already in the base denom
if self.0.contains_key(&coin.denom) {
// if we're converting a base DecCoin it CANNOT fail, unless somebody is providing
// bullshit data on purpose : )
return coin.try_into();
} else {
// TODO: this kinda suggests we may need a better data structure
for registered_coin in self.0.values() {
if let Some(exponent) = registered_coin.get_exponent(&coin.denom) {
let amount = try_convert_decimal_to_u128(coin.try_scale_up_value(exponent)?)?;
return Ok(Coin::new(amount, &registered_coin.base));
}
}
}
Err(TypesError::UnknownCoinDenom(coin.denom))
}
pub fn attempt_convert_to_display_dec_coin(&self, coin: Coin) -> Result<DecCoin, TypesError> {
for registered_coin in self.0.values() {
if let Some(exponent) = registered_coin.get_exponent(&coin.denom) {
// if this fails it means we haven't registered our display denom which honestly should never be the case
// unless somebody is rocking their own custom network
let display_exponent = registered_coin
.get_exponent(&registered_coin.display)
.ok_or_else(|| TypesError::UnknownCoinDenom(coin.denom.clone()))?;
return match exponent.cmp(&display_exponent) {
Ordering::Greater => {
// we need to scale up, unlikely to ever be needed but included for completion sake,
// for example if we decided to created knym with exponent 9 and wanted to convert to nym with exponent 6
Ok(DecCoin::new_scaled_up(
coin.amount,
&registered_coin.display,
exponent - display_exponent,
)?)
}
// we're already in the display denom
Ordering::Equal => Ok(coin.into()),
Ordering::Less => {
// we need to scale down, the most common case, for example we're in base unym with exponent 0 and want to convert to nym with exponent 6
Ok(DecCoin::new_scaled_down(
coin.amount,
&registered_coin.display,
display_exponent - exponent,
)?)
}
};
}
}
Err(TypesError::UnknownCoinDenom(coin.denom))
}
}
// TODO: should this live here?
// attempts to replicate cosmos-sdk's coin metadata
// https://docs.cosmos.network/master/architecture/adr-024-coin-metadata.html
// this way we could more easily handle multiple coin types simultaneously (like nym/nyx/nymt/nyx + local currencies)
#[derive(Debug)]
pub struct DenomUnit {
pub denom: Denom,
pub exponent: u32,
// pub aliases: Vec<String>,
}
impl DenomUnit {
pub fn new(denom: Denom, exponent: u32) -> Self {
DenomUnit { denom, exponent }
}
}
#[derive(Debug)]
pub struct CoinMetadata {
pub denom_units: Vec<DenomUnit>,
pub base: Denom,
pub display: Denom,
}
impl CoinMetadata {
pub fn new(denom_units: Vec<DenomUnit>, base: Denom, display: Denom) -> Self {
CoinMetadata {
denom_units,
base,
display,
}
}
pub fn get_exponent(&self, denom: &str) -> Option<u32> {
self.denom_units
.iter()
.find(|denom_unit| denom_unit.denom == denom)
.map(|denom_unit| denom_unit.exponent)
}
}
impl From<DenomDetails> for CoinMetadata {
fn from(denom_details: DenomDetails) -> Self {
CoinMetadata::new(
vec![
DenomUnit::new(denom_details.base.into(), 0),
DenomUnit::new(denom_details.display.into(), denom_details.display_exponent),
],
denom_details.base.into(),
denom_details.display.into(),
)
}
}
// tries to semi-replicate cosmos-sdk's DecCoin for being able to handle tokens with decimal amounts
// https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/types/dec_coin.go
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct DecCoin {
pub denom: Denom,
// Decimal is already serialized to string and using string in its schema, so lets also go straight to string for ts_rs
// todo: is `Decimal` the correct type to use? Do we want to depend on cosmwasm_std here?
pub amount: Decimal,
}
// I had to implement it manually to correctly set dependencies
#[cfg(feature = "generate-ts")]
impl TS for DecCoin {
const EXPORT_TO: Option<&'static str> = Some("ts-packages/types/src/types/rust/DecCoin.ts");
fn decl() -> String {
format!("type {} = {};", Self::name(), Self::inline())
}
fn name() -> String {
"DecCoin".into()
}
fn inline() -> String {
"{ denom: CurrencyDenom, amount: string }".into()
}
fn dependencies() -> Vec<Dependency> {
vec![Dependency::from_ty::<CurrencyDenom>()
.expect("TS was incorrectly defined on `CurrencyDenom`")]
}
fn transparent() -> bool {
false
}
}
impl DecCoin {
pub fn new_base<S: Into<String>>(amount: impl Into<Uint128>, denom: S) -> Self {
DecCoin {
denom: denom.into(),
amount: Decimal::from_atomics(amount, 0).unwrap(),
}
}
pub fn zero<S: Into<String>>(denom: S) -> Self {
DecCoin {
denom: denom.into(),
amount: Decimal::zero(),
}
}
pub fn new_scaled_up<S: Into<String>>(
base_amount: impl Into<Uint128>,
denom: S,
exponent: u32,
) -> Result<Self, TypesError> {
let base_amount = Decimal::from_atomics(base_amount, 0).unwrap();
Ok(DecCoin {
denom: denom.into(),
amount: try_scale_up_decimal(base_amount, exponent)?,
})
}
pub fn new_scaled_down<S: Into<String>>(
base_amount: impl Into<Uint128>,
denom: S,
exponent: u32,
) -> Result<Self, TypesError> {
let base_amount = Decimal::from_atomics(base_amount, 0).unwrap();
Ok(DecCoin {
denom: denom.into(),
amount: try_scale_down_decimal(base_amount, exponent)?,
})
}
pub fn try_scale_down_value(&self, exponent: u32) -> Result<Decimal, TypesError> {
try_scale_down_decimal(self.amount, exponent)
}
pub fn try_scale_up_value(&self, exponent: u32) -> Result<Decimal, TypesError> {
try_scale_up_decimal(self.amount, exponent)
}
}
// TODO: should thoese live here?
pub fn try_scale_down_decimal(dec: Decimal, exponent: u32) -> Result<Decimal, TypesError> {
let rhs = 10u128
.checked_pow(exponent)
.ok_or(TypesError::UnsupportedExponent(exponent))?;
let denominator = dec
.denominator()
.checked_mul(rhs.into())
.map_err(|_| TypesError::UnsupportedExponent(exponent))?;
Ok(Decimal::from_ratio(dec.numerator(), denominator))
}
pub fn try_scale_up_decimal(dec: Decimal, exponent: u32) -> Result<Decimal, TypesError> {
let rhs = 10u128
.checked_pow(exponent)
.ok_or(TypesError::UnsupportedExponent(exponent))?;
let denominator = dec
.denominator()
.checked_div(rhs.into())
.map_err(|_| TypesError::UnsupportedExponent(exponent))?;
Ok(Decimal::from_ratio(dec.numerator(), denominator))
}
pub fn try_convert_decimal_to_u128(dec: Decimal) -> Result<u128, TypesError> {
let whole = dec.numerator() / dec.denominator();
// unwrap is fine as we're not dividing by zero here
let fractional = (dec.numerator()).checked_rem(dec.denominator()).unwrap();
// we cannot convert as we'd lose our decimal places
// (for example if somebody attempted to represent our gas price (WHICH YOU SHOULDN'T DO) as DecCoin)
if fractional != Uint128::zero() {
return Err(TypesError::LossyCoinConversion);
}
Ok(whole.u128())
}
// TODO: adjust the implementation to as required by @MS or @FT
impl Display for DecCoin {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.amount, self.denom)
}
}
impl From<Coin> for DecCoin {
fn from(coin: Coin) -> Self {
DecCoin::new_base(coin.amount, coin.denom)
}
}
// this conversion assumes same denomination
impl TryFrom<DecCoin> for Coin {
type Error = TypesError;
fn try_from(value: DecCoin) -> Result<Self, Self::Error> {
Ok(Coin {
amount: try_convert_decimal_to_u128(value.try_scale_down_value(0)?)?,
denom: value.denom,
})
}
}
#[cfg(test)]
mod test {
use super::*;
use std::convert::TryFrom;
use std::string::ToString;
#[test]
fn dec_value_scale_down() {
let dec = DecCoin {
denom: "foo".to_string(),
amount: "1234007000".parse().unwrap(),
};
assert_eq!(
"1234007000".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(0).unwrap()
);
assert_eq!(
"123400700".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(1).unwrap()
);
assert_eq!(
"12340070".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(2).unwrap()
);
assert_eq!(
"123400.7".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(4).unwrap()
);
let dec = DecCoin {
denom: "foo".to_string(),
amount: "10000000000".parse().unwrap(),
};
assert_eq!(
"100".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(8).unwrap()
);
assert_eq!(
"1".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(10).unwrap()
);
assert_eq!(
"0.01".parse::<Decimal>().unwrap(),
dec.try_scale_down_value(12).unwrap()
);
}
#[test]
fn dec_value_scale_up() {
let dec = DecCoin {
denom: "foo".to_string(),
amount: "1234.56".parse().unwrap(),
};
assert_eq!(
"1234.56".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(0).unwrap()
);
assert_eq!(
"12345.6".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(1).unwrap()
);
assert_eq!(
"123456".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(2).unwrap()
);
assert_eq!(
"1234560".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(3).unwrap()
);
assert_eq!(
"12345600".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(4).unwrap()
);
let dec = DecCoin {
denom: "foo".to_string(),
amount: "0.00000123".parse().unwrap(),
};
assert_eq!(
"0.0000123".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(1).unwrap()
);
assert_eq!(
"0.000123".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(2).unwrap()
);
assert_eq!(
"123".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(8).unwrap()
);
assert_eq!(
"1230".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(9).unwrap()
);
assert_eq!(
"12300".parse::<Decimal>().unwrap(),
dec.try_scale_up_value(10).unwrap()
);
}
#[test]
fn coin_to_dec_coin() {
let coin = Coin::new(123, "foo");
let dec = DecCoin::from(coin.clone());
assert_eq!(coin.denom, dec.denom);
assert_eq!(dec.amount, Decimal::from_atomics(coin.amount, 0).unwrap());
}
#[test]
fn dec_coin_to_coin() {
let dec = DecCoin {
denom: "foo".to_string(),
amount: "123".parse().unwrap(),
};
let coin = Coin::try_from(dec.clone()).unwrap();
assert_eq!(dec.denom, coin.denom);
assert_eq!(coin.amount, 123u128);
}
#[test]
fn converting_to_display() {
let reg = RegisteredCoins::default_denoms(Network::MAINNET);
let values = vec![
(1u128, "0.000001"),
(10u128, "0.00001"),
(100u128, "0.0001"),
(1000u128, "0.001"),
(10000u128, "0.01"),
(100000u128, "0.1"),
(1000000u128, "1"),
(1234567u128, "1.234567"),
(123456700u128, "123.4567"),
];
for (raw, expected) in values {
let coin = Coin::new(raw, Network::MAINNET.mix_denom().base);
let display = reg.attempt_convert_to_display_dec_coin(coin).unwrap();
assert_eq!(Network::MAINNET.mix_denom().display, display.denom);
assert_eq!(expected, display.amount.to_string());
}
}
#[test]
fn converting_to_base() {
let reg = RegisteredCoins::default_denoms(Network::MAINNET);
let values = vec![
(1u128, "0.000001"),
(10u128, "0.00001"),
(100u128, "0.0001"),
(1000u128, "0.001"),
(10000u128, "0.01"),
(100000u128, "0.1"),
(1000000u128, "1"),
(1234567u128, "1.234567"),
(123456700u128, "123.4567"),
];
for (expected, raw_display) in values {
let coin = DecCoin {
denom: Network::MAINNET.mix_denom().display.into(),
amount: raw_display.parse().unwrap(),
};
let base = reg.attempt_convert_to_base_coin(coin).unwrap();
assert_eq!(Network::MAINNET.mix_denom().base, base.denom);
assert_eq!(expected, base.amount);
}
}
}
+168
View File
@@ -0,0 +1,168 @@
use crate::currency::{DecCoin, RegisteredCoins};
use crate::error::TypesError;
use mixnet_contract_common::mixnode::DelegationEvent as ContractDelegationEvent;
use mixnet_contract_common::mixnode::PendingUndelegate as ContractPendingUndelegate;
use mixnet_contract_common::Delegation as MixnetContractDelegation;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Delegation.ts")
)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
pub struct Delegation {
pub owner: String,
pub node_identity: String,
pub amount: DecCoin,
pub block_height: u64,
pub proxy: Option<String>, // proxy address used to delegate the funds on behalf of another address
}
impl Delegation {
pub fn from_mixnet_contract(
delegation: MixnetContractDelegation,
reg: &RegisteredCoins,
) -> Result<Self, TypesError> {
Ok(Delegation {
owner: delegation.owner.to_string(),
node_identity: delegation.node_identity,
amount: reg.attempt_convert_to_display_dec_coin(delegation.amount.into())?,
block_height: delegation.block_height,
proxy: delegation.proxy.map(|d| d.to_string()),
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationRecord.ts")
)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
pub struct DelegationRecord {
pub amount: DecCoin,
pub block_height: u64,
pub delegated_on_iso_datetime: String,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationWithEverything.ts")
)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
pub struct DelegationWithEverything {
pub owner: String,
pub node_identity: String,
pub amount: DecCoin,
pub total_delegation: Option<DecCoin>,
pub pledge_amount: Option<DecCoin>,
pub block_height: u64,
pub delegated_on_iso_datetime: String,
pub profit_margin_percent: Option<u8>,
pub avg_uptime_percent: Option<u8>,
pub stake_saturation: Option<f32>,
pub proxy: Option<String>,
pub accumulated_rewards: Option<DecCoin>,
pub pending_events: Vec<DelegationEvent>,
pub history: Vec<DelegationRecord>,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationResult.ts")
)]
#[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Debug)]
pub struct DelegationResult {
source_address: String,
target_address: String,
amount: Option<DecCoin>,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationEventKind.ts")
)]
#[derive(Clone, Deserialize, Serialize, PartialEq, JsonSchema, Debug)]
pub enum DelegationEventKind {
Delegate,
Undelegate,
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationEvent.ts")
)]
#[derive(Clone, Deserialize, Serialize, PartialEq, JsonSchema, Debug)]
pub struct DelegationEvent {
pub kind: DelegationEventKind,
pub node_identity: String,
pub address: String,
pub amount: Option<DecCoin>,
pub block_height: u64,
}
impl DelegationEvent {
pub fn from_mixnet_contract(
event: ContractDelegationEvent,
reg: &RegisteredCoins,
) -> Result<Self, TypesError> {
Ok(match event {
ContractDelegationEvent::Delegate(delegation) => DelegationEvent {
kind: DelegationEventKind::Delegate,
block_height: delegation.block_height,
address: delegation.owner.into_string(),
node_identity: delegation.node_identity,
amount: Some(reg.attempt_convert_to_display_dec_coin(delegation.amount.into())?),
},
ContractDelegationEvent::Undelegate(pending_undelegate) => DelegationEvent {
kind: DelegationEventKind::Undelegate,
block_height: pending_undelegate.block_height(),
address: pending_undelegate.delegate().into_string(),
node_identity: pending_undelegate.mix_identity(),
amount: None,
},
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/PendingUndelegate.ts")
)]
#[derive(Deserialize, Serialize, PartialEq, JsonSchema, Clone, Debug)]
pub struct PendingUndelegate {
mix_identity: String,
delegate: String,
proxy: Option<String>,
block_height: u64,
}
impl From<ContractPendingUndelegate> for PendingUndelegate {
fn from(pending_undelegate: ContractPendingUndelegate) -> Self {
PendingUndelegate {
mix_identity: pending_undelegate.mix_identity(),
delegate: pending_undelegate.delegate().to_string(),
proxy: pending_undelegate.proxy().map(|p| p.to_string()),
block_height: pending_undelegate.block_height(),
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/DelegationSummaryResponse.ts")
)]
#[derive(Deserialize, Serialize)]
pub struct DelegationsSummaryResponse {
pub delegations: Vec<DelegationWithEverything>,
pub total_delegations: DecCoin,
pub total_rewards: DecCoin,
}
+90
View File
@@ -0,0 +1,90 @@
use serde::{Serialize, Serializer};
use std::io;
use thiserror::Error;
use validator_client::validator_api::error::ValidatorAPIError;
use validator_client::{nymd::error::NymdError, ValidatorClientError};
// TODO: ask @MS why this even exists
#[derive(Error, Debug)]
pub enum TypesError {
#[error("{source}")]
NymdError {
#[from]
source: NymdError,
},
#[error("{source}")]
CosmwasmStd {
#[from]
source: cosmwasm_std::StdError,
},
#[error("{source}")]
ErrorReport {
#[from]
source: eyre::Report,
},
#[error("{source}")]
ValidatorApiError {
#[from]
source: ValidatorAPIError,
},
#[error("{source}")]
IOError {
#[from]
source: io::Error,
},
#[error("{source}")]
SerdeJsonError {
#[from]
source: serde_json::Error,
},
#[error("{source}")]
MalformedUrlProvided {
#[from]
source: url::ParseError,
},
#[error("{source}")]
ReqwestError {
#[from]
source: reqwest::Error,
},
#[error("{source}")]
DecimalRangeExceeded {
#[from]
source: cosmwasm_std::DecimalRangeExceeded,
},
#[error("{0} is not a valid amount string")]
InvalidAmount(String),
#[error("{0} is not a valid denomination string")]
InvalidDenom(String),
#[error("Mixnode not found")]
MixnodeNotFound(),
#[error("Gateway bond is not valid")]
InvalidGatewayBond(),
#[error("Invalid delegations")]
DelegationsInvalid,
#[error("Attempted to use too huge currency exponent ({0})")]
UnsupportedExponent(u32),
#[error("Attempted to convert coin that would have resulted in loss of precision")]
LossyCoinConversion,
#[error("The provided coin has an unknown denomination - {0}")]
UnknownCoinDenom(String),
}
impl Serialize for TypesError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(self)
}
}
impl From<ValidatorClientError> for TypesError {
fn from(e: ValidatorClientError) -> Self {
match e {
ValidatorClientError::ValidatorAPIError { source } => source.into(),
ValidatorClientError::MalformedUrlProvided(e) => e.into(),
ValidatorClientError::NymdError(e) => e.into(),
}
}
}
+22
View File
@@ -0,0 +1,22 @@
use crate::currency::DecCoin;
use serde::{Deserialize, Serialize};
use validator_client::nymd::Fee;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/FeeDetails.ts")
)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FeeDetails {
// expected to be used by the wallet in order to display detailed fee information to the user
pub amount: Option<DecCoin>,
#[cfg_attr(feature = "generate-ts", ts(skip))]
pub fee: Fee,
}
impl FeeDetails {
pub fn new(amount: Option<DecCoin>, fee: Fee) -> Self {
FeeDetails { amount, fee }
}
}
+60
View File
@@ -0,0 +1,60 @@
use cosmrs::tx::Gas as CosmrsGas;
use serde::{Deserialize, Serialize};
use validator_client::nymd::cosmwasm_client::types::GasInfo as ValidatorClientGasInfo;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Gas.ts")
)]
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct Gas {
/// units of gas used
pub gas_units: u64,
}
impl Gas {
pub fn from_u64(value: u64) -> Gas {
Gas { gas_units: value }
}
}
impl From<CosmrsGas> for Gas {
fn from(gas: CosmrsGas) -> Self {
Gas {
gas_units: gas.value(),
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/GasInfo.ts")
)]
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct GasInfo {
/// GasWanted is the maximum units of work we allow this tx to perform.
pub gas_wanted: Gas,
/// GasUsed is the amount of gas actually consumed.
pub gas_used: Gas,
}
impl From<ValidatorClientGasInfo> for GasInfo {
fn from(info: ValidatorClientGasInfo) -> Self {
GasInfo {
gas_wanted: info.gas_wanted.into(),
gas_used: info.gas_used.into(),
}
}
}
impl GasInfo {
pub fn from_u64(gas_wanted: u64, gas_used: u64) -> GasInfo {
GasInfo {
gas_wanted: Gas::from_u64(gas_wanted),
gas_used: Gas::from_u64(gas_used),
}
}
}
+77
View File
@@ -0,0 +1,77 @@
use crate::currency::{DecCoin, RegisteredCoins};
use crate::error::TypesError;
use mixnet_contract_common::{
Gateway as MixnetContractGateway, GatewayBond as MixnetContractGatewayBond,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Gateway.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub struct Gateway {
pub host: String,
pub mix_port: u16,
pub clients_port: u16,
pub location: String,
pub sphinx_key: String,
/// Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients
pub identity_key: String,
pub version: String,
}
impl From<MixnetContractGateway> for Gateway {
fn from(value: MixnetContractGateway) -> Self {
let MixnetContractGateway {
host,
mix_port,
clients_port,
location,
sphinx_key,
identity_key,
version,
} = value;
Gateway {
host,
mix_port,
clients_port,
location,
sphinx_key,
identity_key,
version,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/GatewayBond.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct GatewayBond {
pub pledge_amount: DecCoin,
pub owner: String,
pub block_height: u64,
pub gateway: Gateway,
pub proxy: Option<String>,
}
impl GatewayBond {
pub fn from_mixnet_contract_gateway_bond(
bond: MixnetContractGatewayBond,
reg: &RegisteredCoins,
) -> Result<GatewayBond, TypesError> {
Ok(GatewayBond {
pledge_amount: reg.attempt_convert_to_display_dec_coin(bond.pledge_amount.into())?,
owner: bond.owner.to_string(),
block_height: bond.block_height,
gateway: bond.gateway.into(),
proxy: bond.proxy.map(|p| p.into_string()),
})
}
}
+10
View File
@@ -0,0 +1,10 @@
pub mod account;
pub mod currency;
pub mod delegation;
pub mod error;
pub mod fees;
pub mod gas;
pub mod gateway;
pub mod mixnode;
pub mod transaction;
pub mod vesting;
+96
View File
@@ -0,0 +1,96 @@
use crate::currency::{DecCoin, RegisteredCoins};
use crate::error::TypesError;
use mixnet_contract_common::{
MixNode as MixnetContractMixNode, MixNodeBond as MixnetContractMixNodeBond,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use validator_client::nymd::Coin;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/Mixnode.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub struct MixNode {
pub host: String,
pub mix_port: u16,
pub verloc_port: u16,
pub http_api_port: u16,
pub sphinx_key: String,
/// Base58 encoded ed25519 EdDSA public key.
pub identity_key: String,
pub version: String,
pub profit_margin_percent: u8,
}
impl From<MixnetContractMixNode> for MixNode {
fn from(value: MixnetContractMixNode) -> Self {
let MixnetContractMixNode {
host,
mix_port,
verloc_port,
http_api_port,
sphinx_key,
identity_key,
version,
profit_margin_percent,
} = value;
Self {
host,
mix_port,
verloc_port,
http_api_port,
sphinx_key,
identity_key,
version,
profit_margin_percent,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/MixNodeBond.ts")
)]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct MixNodeBond {
pub pledge_amount: DecCoin,
pub total_delegation: DecCoin,
pub owner: String,
pub layer: String,
pub block_height: u64,
pub mix_node: MixNode,
pub proxy: Option<String>,
pub accumulated_rewards: Option<DecCoin>,
}
impl MixNodeBond {
pub fn from_mixnet_contract_mixnode_bond(
bond: MixnetContractMixNodeBond,
reg: &RegisteredCoins,
) -> Result<MixNodeBond, TypesError> {
let denom = bond.pledge_amount.denom.clone();
Ok(MixNodeBond {
pledge_amount: reg.attempt_convert_to_display_dec_coin(bond.pledge_amount.into())?,
total_delegation: reg
.attempt_convert_to_display_dec_coin(bond.total_delegation.into())?,
owner: bond.owner.into_string(),
layer: bond.layer.into(),
block_height: bond.block_height,
mix_node: bond.mix_node.into(),
proxy: bond.proxy.map(|p| p.to_string()),
accumulated_rewards: bond
.accumulated_rewards
.map(|reward| {
// here we're making an assumption that rewards always use the same denom as the pledge
// (which I think is a reasonable assumption)
reg.attempt_convert_to_display_dec_coin(Coin::new(reward.u128(), denom))
})
.transpose()?,
})
}
}
+120
View File
@@ -0,0 +1,120 @@
use crate::currency::DecCoin;
use crate::error::TypesError;
use crate::gas::{Gas, GasInfo};
use serde::{Deserialize, Serialize};
use validator_client::nymd::cosmwasm_client::types::ExecuteResult;
use validator_client::nymd::TxResponse;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/SendTxResult.ts")
)]
#[derive(Deserialize, Serialize, Debug)]
pub struct SendTxResult {
pub block_height: u64,
pub code: u32,
pub details: TransactionDetails,
pub gas_used: Gas,
pub gas_wanted: Gas,
pub tx_hash: String,
pub fee: Option<DecCoin>,
}
impl SendTxResult {
pub fn new(t: TxResponse, details: TransactionDetails, fee: Option<DecCoin>) -> SendTxResult {
SendTxResult {
block_height: t.height.value(),
code: t.tx_result.code.value(),
details,
gas_used: t.tx_result.gas_used.into(),
gas_wanted: t.tx_result.gas_wanted.into(),
tx_hash: t.hash.to_string(),
fee,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/TransactionDetails.ts")
)]
#[derive(Deserialize, Serialize, Debug)]
pub struct TransactionDetails {
pub amount: DecCoin,
pub from_address: String,
pub to_address: String,
}
impl TransactionDetails {
pub fn new(amount: DecCoin, from_address: String, to_address: String) -> Self {
TransactionDetails {
amount,
from_address,
to_address,
}
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/TransactionExecuteResult.ts")
)]
#[derive(Deserialize, Serialize)]
pub struct TransactionExecuteResult {
pub logs_json: String,
pub data_json: String,
pub transaction_hash: String,
pub gas_info: GasInfo,
pub fee: Option<DecCoin>,
}
impl TransactionExecuteResult {
pub fn from_execute_result(
value: ExecuteResult,
fee: Option<DecCoin>,
) -> Result<TransactionExecuteResult, TypesError> {
Ok(TransactionExecuteResult {
gas_info: value.gas_info.into(),
transaction_hash: value.transaction_hash.to_string(),
data_json: ::serde_json::to_string_pretty(&value.data)?,
logs_json: ::serde_json::to_string_pretty(&value.logs)?,
fee,
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/RpcTransactionResponse.ts")
)]
#[derive(Deserialize, Serialize)]
pub struct RpcTransactionResponse {
pub index: u32,
pub tx_result_json: String,
pub block_height: u64,
pub transaction_hash: String,
pub gas_used: Gas,
pub gas_wanted: Gas,
pub fee: Option<DecCoin>,
}
impl RpcTransactionResponse {
pub fn from_tx_response(
t: &TxResponse,
fee: Option<DecCoin>,
) -> Result<RpcTransactionResponse, TypesError> {
Ok(RpcTransactionResponse {
index: t.index,
gas_used: t.tx_result.gas_used.into(),
gas_wanted: t.tx_result.gas_wanted.into(),
transaction_hash: t.hash.to_string(),
tx_result_json: ::serde_json::to_string_pretty(&t.tx_result)?,
block_height: t.height.value(),
fee,
})
}
}
+104
View File
@@ -0,0 +1,104 @@
use crate::currency::{DecCoin, RegisteredCoins};
use crate::error::TypesError;
use serde::{Deserialize, Serialize};
use vesting_contract::vesting::Account as ContractVestingAccount;
use vesting_contract::vesting::VestingPeriod as ContractVestingPeriod;
use vesting_contract_common::OriginalVestingResponse as ContractOriginalVestingResponse;
use vesting_contract_common::PledgeData as ContractPledgeData;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/PledgeData.ts")
)]
#[derive(Serialize, Deserialize, Debug)]
pub struct PledgeData {
pub amount: DecCoin,
pub block_time: u64,
}
impl PledgeData {
pub fn from_vesting_contract(
pledge: ContractPledgeData,
reg: &RegisteredCoins,
) -> Result<Self, TypesError> {
Ok(PledgeData {
amount: reg.attempt_convert_to_display_dec_coin(pledge.amount.into())?,
block_time: pledge.block_time.seconds(),
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/OriginalVestingResponse.ts")
)]
#[derive(Serialize, Deserialize, Debug)]
pub struct OriginalVestingResponse {
amount: DecCoin,
number_of_periods: usize,
period_duration: u64,
}
impl OriginalVestingResponse {
pub fn from_vesting_contract(
res: ContractOriginalVestingResponse,
reg: &RegisteredCoins,
) -> Result<Self, TypesError> {
Ok(OriginalVestingResponse {
amount: reg.attempt_convert_to_display_dec_coin(res.amount.into())?,
number_of_periods: res.number_of_periods,
period_duration: res.period_duration,
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/VestingAccountInfo.ts")
)]
#[derive(Serialize, Deserialize, Debug)]
pub struct VestingAccountInfo {
owner_address: String,
staking_address: Option<String>,
start_time: u64,
periods: Vec<VestingPeriod>,
amount: DecCoin,
}
impl VestingAccountInfo {
pub fn from_vesting_contract(
account: ContractVestingAccount,
reg: &RegisteredCoins,
) -> Result<Self, TypesError> {
Ok(VestingAccountInfo {
owner_address: account.owner_address().to_string(),
staking_address: account.staking_address().map(|a| a.to_string()),
start_time: account.start_time().seconds(),
periods: account.periods().into_iter().map(Into::into).collect(),
amount: reg.attempt_convert_to_display_dec_coin(account.coin.into())?,
})
}
}
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
#[cfg_attr(
feature = "generate-ts",
ts(export_to = "ts-packages/types/src/types/rust/VestingPeriod.ts")
)]
#[derive(Serialize, Deserialize, Debug)]
pub struct VestingPeriod {
start_time: u64,
period_seconds: u64,
}
impl From<ContractVestingPeriod> for VestingPeriod {
fn from(period: ContractVestingPeriod) -> Self {
Self {
start_time: period.start_time,
period_seconds: period.period_seconds,
}
}
}
+130 -40
View File
@@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "Inflector"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
[[package]]
name = "aes"
version = "0.7.5"
@@ -60,12 +66,24 @@ dependencies = [
"serde",
]
[[package]]
name = "base16ct"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64ct"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -239,9 +257,9 @@ dependencies = [
[[package]]
name = "const-oid"
version = "0.6.2"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
[[package]]
name = "contracts-common"
@@ -252,9 +270,9 @@ 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",
@@ -265,18 +283,18 @@ dependencies = [
[[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-schema"
version = "1.0.0-beta7"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63f79866e7b2190b6b6cb06959e308183c8d9511a8530f7292073f3cddc963db"
checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da"
dependencies = [
"schemars",
"serde_json",
@@ -284,9 +302,9 @@ dependencies = [
[[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",
@@ -301,9 +319,9 @@ dependencies = [
[[package]]
name = "cosmwasm-storage"
version = "1.0.0-beta8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c4be9fd8c9d3ae7d0c32a925ecbc20707007ce0cba1f7538c0d78b7a2d3729b"
checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5"
dependencies = [
"cosmwasm-std",
"serde",
@@ -340,9 +358,9 @@ dependencies = [
[[package]]
name = "crypto-bigint"
version = "0.2.11"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03"
checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
dependencies = [
"generic-array 0.14.5",
"rand_core 0.6.3",
@@ -394,9 +412,9 @@ dependencies = [
[[package]]
name = "cw-controllers"
version = "0.13.2"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc6d042b14823b0e9f33f5cdd67a1eb9b16a7d79f7547b1a73c8870b518b97b"
checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa"
dependencies = [
"cosmwasm-std",
"cw-storage-plus",
@@ -427,9 +445,9 @@ dependencies = [
[[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",
@@ -438,9 +456,9 @@ dependencies = [
[[package]]
name = "cw-utils"
version = "0.13.2"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e"
checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b"
dependencies = [
"cosmwasm-std",
"schemars",
@@ -538,9 +556,9 @@ dependencies = [
[[package]]
name = "der"
version = "0.4.5"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c"
dependencies = [
"const-oid",
]
@@ -582,13 +600,13 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf"
[[package]]
name = "ecdsa"
version = "0.12.4"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372"
checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9"
dependencies = [
"der",
"elliptic-curve",
"hmac",
"rfc6979",
"signature",
]
@@ -638,16 +656,18 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "elliptic-curve"
version = "0.10.6"
version = "0.11.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b"
checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6"
dependencies = [
"base16ct",
"crypto-bigint",
"der",
"ff",
"generic-array 0.14.5",
"group",
"pkcs8",
"rand_core 0.6.3",
"sec1",
"subtle 2.4.1",
"zeroize",
]
@@ -680,9 +700,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "ff"
version = "0.10.1"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f"
checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924"
dependencies = [
"rand_core 0.6.3",
"subtle 2.4.1",
@@ -787,9 +807,9 @@ dependencies = [
[[package]]
name = "group"
version = "0.10.0"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912"
checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
dependencies = [
"ff",
"rand_core 0.6.3",
@@ -910,13 +930,14 @@ dependencies = [
[[package]]
name = "k256"
version = "0.9.6"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea"
checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d"
dependencies = [
"cfg-if",
"ecdsa",
"elliptic-curve",
"sec1",
"sha2",
]
@@ -1041,6 +1062,7 @@ dependencies = [
"serde_repr",
"thiserror",
"time 0.3.6",
"ts-rs",
]
[[package]]
@@ -1190,12 +1212,13 @@ dependencies = [
[[package]]
name = "pkcs8"
version = "0.7.6"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447"
checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0"
dependencies = [
"der",
"spki",
"zeroize",
]
[[package]]
@@ -1356,6 +1379,17 @@ version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rfc6979"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525"
dependencies = [
"crypto-bigint",
"hmac",
"zeroize",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
@@ -1401,6 +1435,19 @@ dependencies = [
"syn",
]
[[package]]
name = "sec1"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
dependencies = [
"der",
"generic-array 0.14.5",
"pkcs8",
"subtle 2.4.1",
"zeroize",
]
[[package]]
name = "semver"
version = "1.0.4"
@@ -1418,9 +1465,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",
]
@@ -1529,10 +1576,11 @@ dependencies = [
[[package]]
name = "spki"
version = "0.4.1"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32"
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27"
dependencies = [
"base64ct",
"der",
]
@@ -1586,6 +1634,15 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.30"
@@ -1658,6 +1715,29 @@ dependencies = [
"serde",
]
[[package]]
name = "ts-rs"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc59f479df54269b400dd95bc3b7e81623b3e4b9c70c8ca7125ab8341eafa64e"
dependencies = [
"thiserror",
"ts-rs-macros",
]
[[package]]
name = "ts-rs-macros"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f807fdb3151fee75df7485b901a89624358cd07a67a8fb1a5831bf5a07681ff"
dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn",
"termcolor",
]
[[package]]
name = "typenum"
version = "1.15.0"
@@ -1768,6 +1848,7 @@ dependencies = [
"mixnet-contract-common",
"schemars",
"serde",
"ts-rs",
]
[[package]]
@@ -1852,6 +1933,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
+2 -2
View File
@@ -14,8 +14,8 @@ config = { path = "../../common/config"}
[dependencies]
bandwidth-claim-contract = { path = "../../common/bandwidth-claim-contract" }
cosmwasm-std = "1.0.0-beta8"
cosmwasm-storage = "1.0.0-beta8"
cosmwasm-std = "1.0.0"
cosmwasm-storage = "1.0.0"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
+3 -3
View File
@@ -62,7 +62,7 @@ pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Respon
pub mod tests {
use super::*;
use bandwidth_claim_contract::payment::PagedPaymentResponse;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, from_binary};
@@ -91,11 +91,11 @@ pub mod tests {
// Contract balance should match what we initialized it as
assert_eq!(
coins(0, DENOM),
coins(0, MIX_DENOM.base),
vec![deps
.as_ref()
.querier
.query_balance(env.contract.address, DENOM)
.query_balance(env.contract.address, MIX_DENOM.base)
.unwrap()]
);
}
+4 -4
View File
@@ -13,10 +13,10 @@ bandwidth-claim-contract = { path = "../../common/bandwidth-claim-contract" }
coconut-bandwidth-contract-common = { path = "../../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
config = { path = "../../common/config"}
cosmwasm-std = "1.0.0-beta8"
cosmwasm-storage = "1.0.0-beta8"
cw-storage-plus = "0.13.2"
cw-controllers = "0.13.2"
cosmwasm-std = "1.0.0"
cosmwasm-storage = "1.0.0"
cw-storage-plus = "0.13.4"
cw-controllers = "0.13.4"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
+7 -8
View File
@@ -63,11 +63,10 @@ mod tests {
use super::*;
use crate::support::tests::helpers::*;
use coconut_bandwidth_contract_common::deposit::DepositData;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, Addr};
use cw_multi_test::Executor;
use serde::de::Unexpected::Str;
#[test]
fn initialize_contract() {
@@ -84,20 +83,20 @@ mod tests {
// Contract balance should be 0
assert_eq!(
coins(0, DENOM),
coins(0, MIX_DENOM.base),
vec![deps
.as_ref()
.querier
.query_balance(env.contract.address, DENOM)
.query_balance(env.contract.address, MIX_DENOM.base)
.unwrap()]
);
}
#[test]
fn deposit_and_release() {
let init_funds = coins(10, DENOM);
let deposit_funds = coins(1, DENOM);
let release_funds = coins(2, DENOM);
let init_funds = coins(10, MIX_DENOM.base);
let deposit_funds = coins(1, MIX_DENOM.base);
let release_funds = coins(2, MIX_DENOM.base);
let mut app = mock_app(&init_funds);
let multisig_addr = String::from(MULTISIG_CONTRACT);
let pool_addr = String::from(POOL_CONTRACT);
@@ -157,7 +156,7 @@ mod tests {
&[],
)
.unwrap();
let pool_bal = app.wrap().query_balance(pool_addr, DENOM).unwrap();
let pool_bal = app.wrap().query_balance(pool_addr, MIX_DENOM.base).unwrap();
assert_eq!(pool_bal, deposit_funds[0]);
}
}
+2 -2
View File
@@ -5,7 +5,7 @@ use cosmwasm_std::StdError;
use cw_controllers::AdminError;
use thiserror::Error;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
/// Custom errors for contract failure conditions.
///
@@ -22,7 +22,7 @@ pub enum ContractError {
#[error("No coin was sent for voucher")]
NoCoin,
#[error("Wrong coin denomination, you must send {}", DENOM)]
#[error("Wrong coin denomination, you must send {}", MIX_DENOM.base)]
WrongDenom,
#[error("There aren't enough funds in the contract")]
@@ -4,7 +4,6 @@
#[cfg(test)]
pub mod helpers {
pub const OWNER: &str = "admin0001";
pub const SOMEBODY: &str = "somebody";
pub const MULTISIG_CONTRACT: &str = "multisig contract address";
pub const POOL_CONTRACT: &str = "mix pool contract address";
@@ -11,7 +11,7 @@ use coconut_bandwidth_contract_common::events::{
DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_ENCRYPTION_KEY, DEPOSIT_IDENTITY_KEY, DEPOSIT_INFO,
DEPOSIT_VALUE,
};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
pub(crate) fn deposit_funds(
_deps: DepsMut<'_>,
@@ -25,7 +25,7 @@ pub(crate) fn deposit_funds(
if info.funds.len() > 1 {
return Err(ContractError::MultipleDenoms);
}
if info.funds[0].denom != DENOM {
if info.funds[0].denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom);
}
@@ -45,10 +45,12 @@ pub(crate) fn release_funds(
info: MessageInfo,
funds: Coin,
) -> Result<Response, ContractError> {
if funds.denom != DENOM {
if funds.denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom);
}
let current_balance = deps.querier.query_balance(env.contract.address, DENOM)?;
let current_balance = deps
.querier
.query_balance(env.contract.address, MIX_DENOM.base)?;
if funds.amount > current_balance.amount {
return Err(ContractError::NotEnoughFunds);
}
@@ -90,7 +92,7 @@ mod tests {
Err(ContractError::NoCoin)
);
let coin = Coin::new(1000000, DENOM);
let coin = Coin::new(1000000, MIX_DENOM.base);
let second_coin = Coin::new(1000000, "some_denom");
let info = mock_info("requester", &[coin, second_coin.clone()]);
@@ -120,7 +122,7 @@ mod tests {
verification_key.clone(),
encryption_key.clone(),
);
let coin = Coin::new(deposit_value, DENOM);
let coin = Coin::new(deposit_value, MIX_DENOM.base);
let info = mock_info("requester", &[coin]);
let tx = deposit_funds(deps.as_mut(), env.clone(), info, data).unwrap();
@@ -169,7 +171,7 @@ mod tests {
let mut deps = helpers::init_contract();
let env = mock_env();
let invalid_admin = "invalid admin";
let funds = Coin::new(1, DENOM);
let funds = Coin::new(1, MIX_DENOM.base);
let err = release_funds(
deps.as_mut(),
@@ -205,7 +207,7 @@ mod tests {
fn valid_release() {
let mut deps = helpers::init_contract();
let env = mock_env();
let coin = Coin::new(1, DENOM);
let coin = Coin::new(1, MIX_DENOM.base);
deps.querier
.update_balance(env.contract.address.clone(), vec![coin.clone()]);
+4 -4
View File
@@ -20,9 +20,9 @@ mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-
vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" }
config = { path = "../../common/config"}
cosmwasm-std = "1.0.0-beta8"
cosmwasm-storage = "1.0.0-beta8"
cw-storage-plus = "0.13.2"
cosmwasm-std = "1.0.0"
cosmwasm-storage = "1.0.0"
cw-storage-plus = "0.13.4"
az = "1.2.0"
bs58 = "0.4.0"
@@ -33,7 +33,7 @@ time = { version = "0.3", features = ["macros"] }
hex = "0.4.3"
[dev-dependencies]
cosmwasm-schema = "1.0.0-beta3"
cosmwasm-schema = "1.0.0"
fixed = "1.1"
rand_chacha = "0.2"
rand = "0.7"
+3 -2
View File
@@ -475,7 +475,8 @@ pub fn migrate(deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Respons
pub mod tests {
use super::*;
use crate::support::tests;
use config::defaults::{DEFAULT_NETWORK, DENOM};
use config::defaults::DEFAULT_NETWORK;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, from_binary};
use mixnet_contract_common::PagedMixnodeResponse;
@@ -507,7 +508,7 @@ pub mod tests {
// Contract balance should match what we initialized it as
assert_eq!(
coins(0, DENOM),
coins(0, MIX_DENOM.base),
tests::queries::query_contract_balance(env.contract.address, deps)
);
}
+4 -4
View File
@@ -200,7 +200,7 @@ pub(crate) fn query_mixnode_delegations_paged(
pub(crate) mod tests {
use super::*;
use crate::support::tests::test_helpers;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{coin, Addr, Storage};
use rand::Rng;
@@ -385,7 +385,7 @@ pub(crate) mod tests {
let delegation = Delegation::new(
delegation_owner.clone(),
node_identity.clone(),
coin(1234, DENOM),
coin(1234, MIX_DENOM.base),
1234,
None,
);
@@ -433,7 +433,7 @@ pub(crate) mod tests {
let delegation = Delegation::new(
delegation_owner2,
node_identity1.clone(),
coin(1234, DENOM),
coin(1234, MIX_DENOM.base),
1234,
None,
);
@@ -460,7 +460,7 @@ pub(crate) mod tests {
let delegation = Delegation::new(
delegation_owner1.clone(),
node_identity2,
coin(1234, DENOM),
coin(1234, MIX_DENOM.base),
1234,
None,
);
+3 -3
View File
@@ -77,7 +77,7 @@ mod tests {
mod reverse_mix_delegations {
use super::*;
use crate::support::tests::test_helpers;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::mock_env;
use cosmwasm_std::{coin, Order};
use mixnet_contract_common::Delegation;
@@ -87,7 +87,7 @@ mod tests {
let mut deps = test_helpers::init_contract();
let node_identity: IdentityKey = "foo".into();
let delegation_owner = Addr::unchecked("bar");
let delegation = coin(12345, DENOM);
let delegation = coin(12345, MIX_DENOM.base);
let dummy_data = Delegation::new(
delegation_owner.clone(),
@@ -125,7 +125,7 @@ mod tests {
let node_identity2: IdentityKey = "foo2".into();
let delegation_owner1 = Addr::unchecked("bar");
let delegation_owner2 = Addr::unchecked("bar2");
let delegation = coin(12345, DENOM);
let delegation = coin(12345, MIX_DENOM.base);
assert!(test_helpers::read_delegation(
deps.as_ref().storage,
@@ -6,7 +6,7 @@ use super::storage::{self, PENDING_DELEGATION_EVENTS};
use crate::error::ContractError;
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
use crate::mixnodes::storage as mixnodes_storage;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
coins, wasm_execute, Addr, Api, BankMsg, Coin, DepsMut, Env, Event, MessageInfo, Order,
Response, Storage, Uint128, WasmMsg,
@@ -85,7 +85,7 @@ fn validate_delegation_stake(mut delegation: Vec<Coin>) -> Result<Coin, Contract
}
// check that the denomination is correct
if delegation[0].denom != DENOM {
if delegation[0].denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom {});
}
@@ -389,7 +389,7 @@ pub(crate) fn try_reconcile_undelegation(
.as_ref()
.unwrap_or(&pending_undelegate.delegate())
.to_string(),
amount: coins(total_funds.u128(), DENOM),
amount: coins(total_funds.u128(), MIX_DENOM.base),
})
} else {
None
@@ -401,7 +401,7 @@ pub(crate) fn try_reconcile_undelegation(
let msg = Some(VestingContractExecuteMsg::TrackUndelegation {
owner: pending_undelegate.delegate().as_str().to_string(),
mix_identity: pending_undelegate.mix_identity(),
amount: Coin::new(total_funds.u128(), DENOM),
amount: Coin::new(total_funds.u128(), MIX_DENOM.base),
});
wasm_msg = Some(wasm_execute(proxy, &msg, vec![one_ucoin()])?);
@@ -492,7 +492,7 @@ mod tests {
assert_eq!(
Err(ContractError::MultipleDenoms),
validate_delegation_stake(vec![
coin(123, DENOM),
coin(123, MIX_DENOM.base),
coin(123, "BTC"),
coin(123, "DOGE")
])
@@ -511,16 +511,16 @@ mod tests {
fn stake_coin_must_have_value_greater_than_zero() {
assert_eq!(
Err(ContractError::EmptyDelegation),
validate_delegation_stake(coins(0, DENOM))
validate_delegation_stake(coins(0, MIX_DENOM.base))
)
}
#[test]
fn stake_can_have_any_positive_value() {
// this might change in the future, but right now an arbitrary (positive) value can be delegated
assert!(validate_delegation_stake(coins(1, DENOM)).is_ok());
assert!(validate_delegation_stake(coins(123, DENOM)).is_ok());
assert!(validate_delegation_stake(coins(10000000000, DENOM)).is_ok());
assert!(validate_delegation_stake(coins(1, MIX_DENOM.base)).is_ok());
assert!(validate_delegation_stake(coins(123, MIX_DENOM.base)).is_ok());
assert!(validate_delegation_stake(coins(10000000000, MIX_DENOM.base)).is_ok());
}
}
@@ -543,7 +543,7 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("sender", &coins(123, DENOM)),
mock_info("sender", &coins(123, MIX_DENOM.base)),
"non-existent-mix-identity".into(),
)
);
@@ -559,7 +559,7 @@ mod tests {
deps.as_mut(),
);
let delegation_owner = Addr::unchecked("sender");
let delegation = coin(123, DENOM);
let delegation = coin(123, MIX_DENOM.base);
assert!(try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
@@ -616,7 +616,7 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
mock_info(delegation_owner.as_str(), &coins(123, MIX_DENOM.base)),
identity,
)
);
@@ -637,7 +637,7 @@ mod tests {
tests::fixtures::good_mixnode_pledge(),
deps.as_mut(),
);
let delegation = coin(123, DENOM);
let delegation = coin(123, MIX_DENOM.base);
let delegation_owner = Addr::unchecked("sender");
assert!(try_delegate_to_mixnode(
deps.as_mut(),
@@ -687,8 +687,8 @@ mod tests {
deps.as_mut(),
);
let delegation_owner = Addr::unchecked("sender");
let delegation1 = coin(100, DENOM);
let delegation2 = coin(50, DENOM);
let delegation1 = coin(100, MIX_DENOM.base);
let delegation2 = coin(50, MIX_DENOM.base);
let mut env = mock_env();
@@ -715,7 +715,7 @@ mod tests {
// let expected = Delegation::new(
// delegation_owner.clone(),
// identity.clone(),
// coin(delegation1.amount.u128() + delegation2.amount.u128(), DENOM),
// coin(delegation1.amount.u128() + delegation2.amount.u128(), MIX_DENOM.base),
// mock_env().block.height,
// None,
// );
@@ -750,7 +750,7 @@ mod tests {
deps.as_mut(),
);
let delegation_owner = Addr::unchecked("sender");
let delegation = coin(100, DENOM);
let delegation = coin(100, MIX_DENOM.base);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
@@ -815,8 +815,8 @@ mod tests {
);
let delegation_owner1 = Addr::unchecked("sender1");
let delegation_owner2 = Addr::unchecked("sender2");
let delegation1 = coin(100, DENOM);
let delegation2 = coin(120, DENOM);
let delegation1 = coin(100, MIX_DENOM.base);
let delegation2 = coin(120, MIX_DENOM.base);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
@@ -891,7 +891,7 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
mock_info(delegation_owner.as_str(), &coins(100, MIX_DENOM.base)),
identity.clone(),
)
.unwrap();
@@ -903,7 +903,7 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(50, DENOM)),
mock_info(delegation_owner.as_str(), &coins(50, MIX_DENOM.base)),
identity,
)
);
@@ -928,14 +928,14 @@ mod tests {
assert!(try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
mock_info(delegation_owner.as_str(), &coins(123, MIX_DENOM.base)),
identity1.clone(),
)
.is_ok());
assert!(try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(42, DENOM)),
mock_info(delegation_owner.as_str(), &coins(42, MIX_DENOM.base)),
identity2.clone(),
)
.is_ok());
@@ -945,7 +945,7 @@ mod tests {
let expected1 = Delegation::new(
delegation_owner.clone(),
identity1.clone(),
coin(123, DENOM),
coin(123, MIX_DENOM.base),
mock_env().block.height,
None,
);
@@ -953,7 +953,7 @@ mod tests {
let expected2 = Delegation::new(
delegation_owner.clone(),
identity2.clone(),
coin(42, DENOM),
coin(42, MIX_DENOM.base),
mock_env().block.height,
None,
);
@@ -989,8 +989,8 @@ mod tests {
tests::fixtures::good_mixnode_pledge(),
deps.as_mut(),
);
let delegation1 = coin(123, DENOM);
let delegation2 = coin(234, DENOM);
let delegation1 = coin(123, MIX_DENOM.base);
let delegation2 = coin(234, MIX_DENOM.base);
assert!(try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
@@ -1026,7 +1026,7 @@ mod tests {
deps.as_mut(),
);
let delegation_owner = Addr::unchecked("sender");
let delegation_amount = coin(100, DENOM);
let delegation_amount = coin(100, MIX_DENOM.base);
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
@@ -1118,7 +1118,7 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
mock_info(delegation_owner.as_str(), &coins(100, MIX_DENOM.base)),
identity.clone(),
)
.unwrap();
@@ -1137,7 +1137,7 @@ mod tests {
let expected_response = Response::new()
.add_message(BankMsg::Send {
to_address: delegation_owner.clone().into(),
amount: coins(100, DENOM),
amount: coins(100, MIX_DENOM.base),
})
.add_event(new_undelegation_event(
&delegation_owner,
@@ -1188,14 +1188,14 @@ mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
mock_info(delegation_owner.as_str(), &coins(100, MIX_DENOM.base)),
identity.clone(),
)
.unwrap();
_try_reconcile_all_delegation_events(&mut deps.storage, &deps.api).unwrap();
let delegation = query_mixnode_delegation(
let _delegation = query_mixnode_delegation(
&deps.storage,
&deps.api,
identity.clone(),
@@ -1207,7 +1207,7 @@ mod tests {
let expected_response = Response::new()
.add_message(BankMsg::Send {
to_address: delegation_owner.clone().into(),
amount: coins(100, DENOM),
amount: coins(100, MIX_DENOM.base),
})
.add_event(new_undelegation_event(
&delegation_owner,
@@ -1251,8 +1251,8 @@ mod tests {
);
let delegation_owner1 = Addr::unchecked("sender1");
let delegation_owner2 = Addr::unchecked("sender2");
let delegation1 = coin(123, DENOM);
let delegation2 = coin(234, DENOM);
let delegation1 = coin(123, MIX_DENOM.base);
let delegation2 = coin(234, MIX_DENOM.base);
assert!(try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
+3 -3
View File
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{Addr, StdError};
use mixnet_contract_common::{error::MixnetContractError, IdentityKey};
use thiserror::Error;
@@ -33,13 +33,13 @@ pub enum ContractError {
#[error("MIXNET ({}): Unauthorized", line!())]
Unauthorized,
#[error("MIXNET ({}): Wrong coin denomination, you must send {}", line!(), DENOM)]
#[error("MIXNET ({}): Wrong coin denomination, you must send {}", line!(), MIX_DENOM.base)]
WrongDenom,
#[error("MIXNET ({}): Received multiple coin types during staking", line!())]
MultipleDenoms,
#[error("MIXNET ({}): No coin was sent for the bonding, you must send {}", line!(), DENOM)]
#[error("MIXNET ({}): No coin was sent for the bonding, you must send {}", line!(), MIX_DENOM.base)]
NoBondFound,
#[error("MIXNET ({}): Provided active set size is bigger than the rewarded set", line!())]
+2 -2
View File
@@ -36,7 +36,7 @@ pub(crate) fn gateways<'a>() -> IndexedMap<'a, IdentityKeyRef<'a>, GatewayBond,
mod tests {
use super::super::storage;
use crate::support::tests;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::MockStorage;
use cosmwasm_std::StdResult;
use cosmwasm_std::Storage;
@@ -84,7 +84,7 @@ mod tests {
let pledge_amount = 1000;
let gateway_bond = GatewayBond {
pledge_amount: coin(pledge_amount, DENOM),
pledge_amount: coin(pledge_amount, MIX_DENOM.base),
owner: node_owner,
block_height: 12_345,
gateway: Gateway {
@@ -5,7 +5,7 @@ use super::storage;
use crate::error::ContractError;
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
use crate::support::helpers::{ensure_no_existing_bond, validate_node_identity_signature};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Uint128,
};
@@ -203,7 +203,7 @@ fn validate_gateway_pledge(
}
// check that the denomination is correct
if pledge[0].denom != DENOM {
if pledge[0].denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom {});
}
@@ -226,7 +226,7 @@ pub mod tests {
use crate::gateways::transactions::validate_gateway_pledge;
use crate::support::tests;
use crate::support::tests::test_helpers;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coins, BankMsg, Response};
use cosmwasm_std::{from_binary, Addr, Uint128};
@@ -238,7 +238,7 @@ pub mod tests {
// if we fail validation (by say not sending enough funds
let insufficient_bond = Into::<u128>::into(INITIAL_GATEWAY_PLEDGE) - 1;
let info = mock_info("anyone", &coins(insufficient_bond, DENOM));
let info = mock_info("anyone", &coins(insufficient_bond, MIX_DENOM.base));
let (msg, _) = tests::messages::valid_bond_gateway_msg("anyone");
// we are informed that we didn't send enough funds
+4 -4
View File
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{StdResult, Storage, Uint128};
use cw_storage_plus::{Index, IndexList, IndexedSnapshotMap, Map, Strategy, UniqueIndex};
use mixnet_contract_common::{
@@ -171,7 +171,7 @@ pub(crate) fn read_full_mixnode_bond(
Ok(Some(MixNodeBond {
pledge_amount: stored_bond.pledge_amount,
total_delegation: Coin {
denom: DENOM.to_owned(),
denom: MIX_DENOM.base.to_owned(),
amount: total_delegation.unwrap_or_default(),
},
owner: stored_bond.owner,
@@ -190,7 +190,7 @@ mod tests {
use super::super::storage;
use super::*;
use crate::support::tests;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::MockStorage;
use cosmwasm_std::{coin, Addr, Uint128};
use mixnet_contract_common::{IdentityKey, MixNode};
@@ -223,7 +223,7 @@ mod tests {
let pledge_value = 1000000000;
let mixnode_bond = StoredMixnodeBond {
pledge_amount: coin(pledge_value, DENOM),
pledge_amount: coin(pledge_value, MIX_DENOM.base),
owner: node_owner,
layer: Layer::One,
block_height: 12_345,
@@ -7,7 +7,7 @@ use crate::mixnet_contract_settings::storage as mixnet_params_storage;
use crate::mixnodes::layer_queries::query_layer_distribution;
use crate::mixnodes::storage::StoredMixnodeBond;
use crate::support::helpers::{ensure_no_existing_bond, validate_node_identity_signature};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Storage, Uint128,
};
@@ -364,7 +364,7 @@ fn validate_mixnode_pledge(
}
// check that the denomination is correct
if pledge[0].denom != DENOM {
if pledge[0].denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom {});
}
@@ -381,15 +381,13 @@ fn validate_mixnode_pledge(
#[cfg(test)]
pub mod tests {
use std::f64::MIN;
use super::*;
use crate::contract::{execute, query, INITIAL_MIXNODE_PLEDGE};
use crate::error::ContractError;
use crate::mixnodes::transactions::validate_mixnode_pledge;
use crate::support::tests;
use crate::support::tests::test_helpers;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coins, BankMsg, Response};
use cosmwasm_std::{from_binary, Addr, Uint128};
@@ -404,7 +402,7 @@ pub mod tests {
// if we don't send enough funds
let insufficient_bond = Into::<u128>::into(INITIAL_MIXNODE_PLEDGE) - 1;
let info = mock_info("anyone", &coins(insufficient_bond, DENOM));
let info = mock_info("anyone", &coins(insufficient_bond, MIX_DENOM.base));
let (msg, _) = tests::messages::valid_bond_mixnode_msg("anyone");
// we are informed that we didn't send enough funds
+5 -2
View File
@@ -79,7 +79,7 @@ pub(crate) mod tests {
use crate::delegations::transactions::try_delegate_to_mixnode;
use crate::interval::storage::{save_epoch, save_epoch_reward_params};
use crate::rewards::transactions::try_reward_mixnode;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{coin, Addr};
use mixnet_contract_common::{
Interval, RewardingResult, RewardingStatus, MIXNODE_DELEGATORS_PAGE_LIMIT,
@@ -181,7 +181,10 @@ pub(crate) mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
env.clone(),
mock_info(&*format!("delegator{:04}", i), &[coin(200_000000, DENOM)]),
mock_info(
&*format!("delegator{:04}", i),
&[coin(200_000000, MIX_DENOM.base)],
),
node_identity.clone(),
)
.unwrap();
+30 -28
View File
@@ -14,7 +14,7 @@ use crate::mixnodes::storage::mixnodes;
use crate::mixnodes::storage::{self as mixnodes_storage, StoredMixnodeBond};
use crate::rewards::helpers;
use crate::support::helpers::is_authorized;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
coins, wasm_execute, Addr, Api, BankMsg, Coin, DepsMut, Env, MessageInfo, Order, Response,
Storage, Uint128,
@@ -105,7 +105,7 @@ fn _try_claim_operator_reward(
let return_tokens = BankMsg::Send {
to_address: proxy.as_ref().unwrap_or(&owner).to_string(),
amount: coins(reward.u128(), DENOM),
amount: coins(reward.u128(), MIX_DENOM.base),
};
let mut response = Response::default()
@@ -115,7 +115,7 @@ fn _try_claim_operator_reward(
if let Some(proxy) = proxy {
let msg = Some(VestingContractExecuteMsg::TrackReward {
address: owner.to_string(),
amount: Coin::new(reward.u128(), DENOM),
amount: Coin::new(reward.u128(), MIX_DENOM.base),
});
let wasm_msg = wasm_execute(proxy, &msg, vec![one_ucoin()])?;
@@ -153,7 +153,7 @@ pub fn _try_claim_delegator_reward(
let return_tokens = BankMsg::Send {
to_address: proxy.as_ref().unwrap_or(&owner).to_string(),
amount: coins(reward.u128(), DENOM),
amount: coins(reward.u128(), MIX_DENOM.base),
};
let mut response =
@@ -169,7 +169,7 @@ pub fn _try_claim_delegator_reward(
if let Some(proxy) = proxy {
let msg = Some(VestingContractExecuteMsg::TrackReward {
address: owner.to_string(),
amount: Coin::new(reward.u128(), DENOM),
amount: Coin::new(reward.u128(), MIX_DENOM.base),
});
let wasm_msg = wasm_execute(proxy, &msg, vec![one_ucoin()])?;
@@ -436,7 +436,7 @@ pub fn _try_compound_delegator_reward(
owner_address,
Coin {
amount: compounded_delegation,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
proxy,
)?;
@@ -721,7 +721,7 @@ pub mod tests {
use crate::support::tests;
use crate::support::tests::test_helpers;
use az::CheckedCast;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coin, coins, Addr, StdError, Timestamp, Uint128};
use mixnet_contract_common::events::{
@@ -737,7 +737,7 @@ pub mod tests {
let mut deps = test_helpers::init_contract();
let mut env = mock_env();
let sender = rewarding_validator_address(&deps.storage).unwrap();
let info = mock_info(&sender, &coins(1000, DENOM));
let info = mock_info(&sender, &coins(1000, MIX_DENOM.base));
crate::interval::transactions::init_epoch(&mut deps.storage, env.clone()).unwrap();
// bond the node
@@ -878,7 +878,7 @@ pub mod tests {
let initial_bond = 10000_000000;
let initial_delegation = 20000_000000;
let mixnode_bond = StoredMixnodeBond {
pledge_amount: coin(initial_bond, DENOM),
pledge_amount: coin(initial_bond, MIX_DENOM.base),
owner: node_owner,
layer: Layer::One,
block_height: env.block.height,
@@ -918,7 +918,7 @@ pub mod tests {
&Delegation::new(
Addr::unchecked("delegator"),
node_identity.clone(),
coin(initial_delegation, DENOM),
coin(initial_delegation, MIX_DENOM.base),
env.block.height,
None,
),
@@ -1098,7 +1098,7 @@ pub mod tests {
assert_eq!(circulating_supply, 750_000_000_000_000u128);
let sender = Addr::unchecked("alice");
let stake = coins(10_000_000_000, DENOM);
let stake = coins(10_000_000_000, MIX_DENOM.base);
let keypair = crypto::asymmetric::identity::KeyPair::new(&mut thread_rng());
let owner_signature = keypair
@@ -1151,14 +1151,14 @@ pub mod tests {
let node_owner: Addr = Addr::unchecked("johnny");
let node_identity_2 = test_helpers::add_mixnode(
node_owner.as_str(),
coins(10_000_000_000, DENOM),
coins(10_000_000_000, MIX_DENOM.base),
deps.as_mut(),
);
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alice_d1", &[coin(8000_000000, DENOM)]),
mock_info("alice_d1", &[coin(8000_000000, MIX_DENOM.base)]),
node_identity_1.clone(),
)
.unwrap();
@@ -1166,7 +1166,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alice_d2", &[coin(2000_000000, DENOM)]),
mock_info("alice_d2", &[coin(2000_000000, MIX_DENOM.base)]),
node_identity_1.clone(),
)
.unwrap();
@@ -1174,7 +1174,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("bob_d1", &[coin(8000_000000, DENOM)]),
mock_info("bob_d1", &[coin(8000_000000, MIX_DENOM.base)]),
node_identity_2.clone(),
)
.unwrap();
@@ -1182,7 +1182,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("bob_d2", &[coin(2000_000000, DENOM)]),
mock_info("bob_d2", &[coin(2000_000000, MIX_DENOM.base)]),
node_identity_2.clone(),
)
.unwrap();
@@ -1190,14 +1190,14 @@ pub mod tests {
let node_owner: Addr = Addr::unchecked("alicebob");
let node_identity_3 = test_helpers::add_mixnode(
node_owner.as_str(),
coins(10_000_000_000 * 2, DENOM),
coins(10_000_000_000 * 2, MIX_DENOM.base),
deps.as_mut(),
);
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alicebob_d1", &[coin(8000_000000 * 2, DENOM)]),
mock_info("alicebob_d1", &[coin(8000_000000 * 2, MIX_DENOM.base)]),
node_identity_3.clone(),
)
.unwrap();
@@ -1205,7 +1205,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alicebob_d2", &[coin(2000_000000 * 2, DENOM)]),
mock_info("alicebob_d2", &[coin(2000_000000 * 2, MIX_DENOM.base)]),
node_identity_3.clone(),
)
.unwrap();
@@ -1216,7 +1216,6 @@ pub mod tests {
)
.unwrap();
let info = mock_info(rewarding_validator_address.as_ref(), &[]);
env.block.height += 2 * constants::MINIMUM_BLOCK_AGE_FOR_REWARDING;
let mix_1 = mixnodes_storage::read_full_mixnode_bond(&deps.storage, &node_identity_1)
@@ -1305,7 +1304,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
env.clone(),
mock_info("alice_d1", &[coin(8000_000000, DENOM)]),
mock_info("alice_d1", &[coin(8000_000000, MIX_DENOM.base)]),
node_identity_1.clone(),
)
.unwrap();
@@ -1506,7 +1505,7 @@ pub mod tests {
);
assert_eq!(mix_2_reward_result.reward().int(), 129557u128);
let mix_3_reward_result = mix_3.reward(&params3);
let _mix_3_reward_result = mix_3.reward(&params3);
// assert_eq!(mix_3_reward_result.reward().int(), mix_1_reward_result.reward().int() + mix_2_reward_result.reward().int());
}
@@ -1533,14 +1532,14 @@ pub mod tests {
let node_owner: Addr = Addr::unchecked("alice");
let node_identity = test_helpers::add_mixnode(
node_owner.as_str(),
coins(10_000_000_000, DENOM),
coins(10_000_000_000, MIX_DENOM.base),
deps.as_mut(),
);
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alice_d1", &[coin(8000_000000, DENOM)]),
mock_info("alice_d1", &[coin(8000_000000, MIX_DENOM.base)]),
node_identity.clone(),
)
.unwrap();
@@ -1548,7 +1547,7 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
mock_env(),
mock_info("alice_d2", &[coin(2000_000000, DENOM)]),
mock_info("alice_d2", &[coin(2000_000000, MIX_DENOM.base)]),
node_identity.clone(),
)
.unwrap();
@@ -1698,7 +1697,7 @@ pub mod tests {
#[allow(clippy::inconsistent_digit_grouping)]
let node_identity = test_helpers::add_mixnode(
node_owner.as_str(),
coins(10000_000_000, DENOM),
coins(10000_000_000, MIX_DENOM.base),
deps.as_mut(),
);
@@ -1725,7 +1724,7 @@ pub mod tests {
#[allow(clippy::inconsistent_digit_grouping)]
let node_identity = test_helpers::add_mixnode(
node_owner.as_str(),
coins(10000_000_000, DENOM),
coins(10000_000_000, MIX_DENOM.base),
deps.as_mut(),
);
@@ -1733,7 +1732,10 @@ pub mod tests {
try_delegate_to_mixnode(
deps.as_mut(),
env.clone(),
mock_info(&*format!("delegator{:04}", i), &[coin(2000_000000, DENOM)]),
mock_info(
&*format!("delegator{:04}", i),
&[coin(2000_000000, MIX_DENOM.base)],
),
node_identity.clone(),
)
.unwrap();
@@ -1,7 +1,7 @@
use crate::contract::INITIAL_MIXNODE_PLEDGE;
use crate::mixnodes::storage as mixnodes_storage;
use crate::{mixnodes::storage::StoredMixnodeBond, support::tests};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{coin, Addr, Coin};
use mixnet_contract_common::reward_params::NodeRewardParams;
use mixnet_contract_common::{Gateway, GatewayBond, Layer, MixNode};
@@ -37,7 +37,7 @@ pub fn gateway_bond_fixture(owner: &str) -> GatewayBond {
..tests::fixtures::gateway_fixture()
};
GatewayBond::new(
coin(50, DENOM),
coin(50, MIX_DENOM.base),
Addr::unchecked(owner),
12_345,
gateway,
@@ -47,7 +47,7 @@ pub fn gateway_bond_fixture(owner: &str) -> GatewayBond {
pub(crate) fn stored_mixnode_bond_fixture(owner: &str) -> mixnodes_storage::StoredMixnodeBond {
StoredMixnodeBond::new(
coin(50, DENOM),
coin(50, MIX_DENOM.base),
Addr::unchecked(owner),
Layer::One,
12_345,
@@ -64,14 +64,14 @@ pub(crate) fn stored_mixnode_bond_fixture(owner: &str) -> mixnodes_storage::Stor
pub fn good_mixnode_pledge() -> Vec<Coin> {
vec![Coin {
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
amount: INITIAL_MIXNODE_PLEDGE,
}]
}
pub fn good_gateway_pledge() -> Vec<Coin> {
vec![Coin {
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
amount: INITIAL_MIXNODE_PLEDGE,
}]
}
+2 -2
View File
@@ -17,7 +17,7 @@ pub mod test_helpers {
use crate::mixnodes::storage as mixnodes_storage;
use crate::mixnodes::transactions::try_add_mixnode;
use crate::support::tests;
use config::defaults::{DEFAULT_NETWORK, DENOM};
use config::defaults::{DEFAULT_NETWORK, MIX_DENOM};
use cosmwasm_std::testing::mock_dependencies;
use cosmwasm_std::testing::mock_env;
use cosmwasm_std::testing::mock_info;
@@ -111,7 +111,7 @@ pub mod test_helpers {
let delegation = Delegation {
owner: Addr::unchecked(owner.into()),
node_identity: mix.into(),
amount: coin(12345, DENOM),
amount: coin(12345, MIX_DENOM.base),
block_height: block_height,
proxy: None,
};
@@ -1,4 +1,4 @@
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
from_binary,
testing::{mock_env, MockApi, MockQuerier, MockStorage},
@@ -45,5 +45,5 @@ pub fn query_contract_balance(
deps: OwnedDeps<MockStorage, MockApi, MockQuerier>,
) -> Vec<Coin> {
let querier = deps.as_ref().querier;
vec![querier.query_balance(address, DENOM).unwrap()]
vec![querier.query_balance(address, MIX_DENOM.base).unwrap()]
}
@@ -23,7 +23,7 @@ cw3 = { version = "0.13.1" }
cw3-fixed-multisig = { version = "0.13.1", features = ["library"] }
cw4 = { version = "0.13.1" }
cw-storage-plus = { version = "0.13.1" }
cosmwasm-std = { version = "1.0.0-beta6" }
cosmwasm-std = { version = "1.0.0" }
schemars = "0.8.1"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.23" }
@@ -31,6 +31,6 @@ thiserror = { version = "1.0.23" }
multisig-contract-common = { path= "../../../common/cosmwasm-smart-contracts/multisig-contract" }
[dev-dependencies]
cosmwasm-schema = { version = "1.0.0-beta6" }
cosmwasm-schema = { version = "1.0.0" }
cw4-group = { path = "../cw4-group", version = "0.13.1" }
cw-multi-test = { version = "0.13.1" }
+2 -2
View File
@@ -29,10 +29,10 @@ cw2 = { version = "0.13.1" }
cw4 = { version = "0.13.1" }
cw-controllers = { version = "0.13.1" }
cw-storage-plus = { version = "0.13.1" }
cosmwasm-std = { version = "1.0.0-beta6" }
cosmwasm-std = { version = "1.0.0" }
schemars = "0.8.1"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.23" }
[dev-dependencies]
cosmwasm-schema = { version = "1.0.0-beta6" }
cosmwasm-schema = { version = "1.0.0" }
+2 -2
View File
@@ -18,8 +18,8 @@ mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-
vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" }
config = { path = "../../common/config" }
cosmwasm-std = { version = "1.0.0-beta8"}
cw-storage-plus = { version = "0.13.1", features = ["iterator"] }
cosmwasm-std = { version = "1.0.0 "}
cw-storage-plus = { version = "0.13.4", features = ["iterator"] }
schemars = "0.8"
serde = { version = "1.0", default-features = false, features = ["derive"] }
+8 -5
View File
@@ -4,7 +4,7 @@ use crate::traits::{
DelegatingAccount, GatewayBondingAccount, MixnodeBondingAccount, VestingAccount,
};
use crate::vesting::{populate_vesting_periods, Account};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{
coin, entry_point, to_binary, BankMsg, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse,
Response, Timestamp,
@@ -147,8 +147,11 @@ pub fn try_withdraw_vested_coins(
info: MessageInfo,
deps: DepsMut<'_>,
) -> Result<Response, ContractError> {
if amount.denom != DENOM {
return Err(ContractError::WrongDenom(amount.denom, DENOM.to_string()));
if amount.denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom(
amount.denom,
MIX_DENOM.base.to_string(),
));
}
let address = info.sender.clone();
@@ -611,10 +614,10 @@ fn validate_funds(funds: &[Coin]) -> Result<Coin, ContractError> {
return Err(ContractError::MultipleDenoms);
}
if funds[0].denom != DENOM {
if funds[0].denom != MIX_DENOM.base {
return Err(ContractError::WrongDenom(
funds[0].denom.clone(),
DENOM.to_string(),
MIX_DENOM.base.to_string(),
));
}
+3 -3
View File
@@ -2,7 +2,7 @@
pub mod helpers {
use crate::contract::instantiate;
use crate::vesting::{populate_vesting_periods, Account};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier};
use cosmwasm_std::{Addr, Coin, Empty, Env, MemoryStorage, OwnedDeps, Storage, Uint128};
use vesting_contract_common::messages::{InitMsg, VestingSpecification};
@@ -31,7 +31,7 @@ pub mod helpers {
Some(Addr::unchecked("staking")),
Coin {
amount: Uint128::new(1_000_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
start_time_ts,
periods,
@@ -50,7 +50,7 @@ pub mod helpers {
Some(Addr::unchecked("staking")),
Coin {
amount: Uint128::new(1_000_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
start_time,
periods,
+5 -5
View File
@@ -25,11 +25,11 @@ fn generate_storage_key(storage: &mut dyn Storage) -> Result<u32, ContractError>
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Account {
owner_address: Addr,
staking_address: Option<Addr>,
start_time: Timestamp,
periods: Vec<VestingPeriod>,
coin: Coin,
pub owner_address: Addr,
pub staking_address: Option<Addr>,
pub start_time: Timestamp,
pub periods: Vec<VestingPeriod>,
pub coin: Coin,
storage_key: u32,
}
@@ -1,7 +1,7 @@
use crate::errors::ContractError;
use crate::storage::{delete_account, save_account, DELEGATIONS};
use crate::traits::VestingAccount;
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::{Addr, Coin, Env, Order, Storage, Timestamp, Uint128};
use vesting_contract_common::{OriginalVestingResponse, Period};
@@ -38,7 +38,7 @@ impl VestingAccount for Account {
.u128(),
),
),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -54,7 +54,7 @@ impl VestingAccount for Account {
.u128()
.saturating_sub(self.locked_coins(block_time, env, storage)?.amount.u128()),
),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -69,15 +69,15 @@ impl VestingAccount for Account {
let amount = match period {
Period::Before => Coin {
amount: Uint128::new(0),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
Period::In(idx) => Coin {
amount: Uint128::new(self.tokens_per_period()? * idx as u128),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
Period::After => Coin {
amount: self.coin.amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
};
Ok(amount)
@@ -91,7 +91,7 @@ impl VestingAccount for Account {
Ok(Coin {
amount: self.get_original_vesting().amount().amount
- self.get_vested_coins(block_time, env)?.amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -143,7 +143,7 @@ impl VestingAccount for Account {
Ok(Coin {
amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -161,7 +161,7 @@ impl VestingAccount for Account {
Ok(Coin {
amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -197,7 +197,7 @@ impl VestingAccount for Account {
Ok(Coin {
amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
@@ -217,12 +217,12 @@ impl VestingAccount for Account {
let amount = bond.amount().amount - bonded_free.amount;
Ok(Coin {
amount,
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
} else {
Ok(Coin {
amount: Uint128::zero(),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
})
}
}
+14 -14
View File
@@ -44,7 +44,7 @@ mod tests {
use crate::traits::DelegatingAccount;
use crate::traits::VestingAccount;
use crate::traits::{GatewayBondingAccount, MixnodeBondingAccount};
use config::defaults::DENOM;
use config::defaults::MIX_DENOM;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coins, Addr, Coin, Timestamp, Uint128};
use mixnet_contract_common::{Gateway, MixNode};
@@ -55,7 +55,7 @@ mod tests {
fn test_account_creation() {
let mut deps = init_contract();
let env = mock_env();
let info = mock_info("not_admin", &coins(1_000_000_000_000, DENOM));
let info = mock_info("not_admin", &coins(1_000_000_000_000, MIX_DENOM.base));
let msg = ExecuteMsg::CreateAccount {
owner_address: "owner".to_string(),
staking_address: Some("staking".to_string()),
@@ -65,7 +65,7 @@ mod tests {
let response = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone());
assert!(response.is_err());
let info = mock_info("admin", &coins(1_000_000_000_000, DENOM));
let info = mock_info("admin", &coins(1_000_000_000_000, MIX_DENOM.base));
let _response = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone());
let created_account = load_account(&Addr::unchecked("owner"), &deps.storage)
.unwrap()
@@ -131,7 +131,7 @@ mod tests {
let msg = ExecuteMsg::WithdrawVestedCoins {
amount: Coin {
amount: Uint128::new(1),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
};
let info = mock_info("new_owner", &[]);
@@ -262,7 +262,7 @@ mod tests {
let delegation = Coin {
amount: Uint128::new(500_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
};
let ok = account.try_delegate_to_mixnode(
@@ -388,7 +388,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(1_000_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -399,7 +399,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -414,7 +414,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -510,7 +510,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(1_000_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -522,7 +522,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -538,7 +538,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -630,7 +630,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(1_000_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -642,7 +642,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_000),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -658,7 +658,7 @@ mod tests {
"alice".to_string(),
Coin {
amount: Uint128::new(500_000_000_001),
denom: DENOM.to_string(),
denom: MIX_DENOM.base.to_string(),
},
&env,
&mut deps.storage,
@@ -91,14 +91,14 @@ export const BondBreakdownTable: React.FC = () => {
}}
align="left"
>
Bond total
Stake total
</TableCell>
<TableCell align="left" data-testid="bond-total-amount">
{bonds.bondsTotal}
</TableCell>
</TableRow>
<TableRow>
<TableCell align="left">Self</TableCell>
<TableCell align="left">Bond</TableCell>
<TableCell align="left" data-testid="pledge-total-amount">
{bonds.pledges}
</TableCell>
@@ -177,7 +177,7 @@ export const BondBreakdownTable: React.FC = () => {
}}
align="left"
>
Stake
Amount
</TableCell>
<TableCell
sx={{
@@ -187,7 +187,7 @@ export const BondBreakdownTable: React.FC = () => {
}}
align="left"
>
Share from bond
Share of stake
</TableCell>
</TableRow>
</TableHead>
+2 -2
View File
@@ -29,7 +29,7 @@ const columns: ColumnsType[] = [
{
field: 'bond',
title: 'Bond',
title: 'Stake',
flex: 1,
headerAlign: 'left',
},
@@ -95,7 +95,7 @@ const PageMixnodeDetailWithState: React.FC = () => {
<Grid container spacing={2} mt={0}>
<Grid item xs={12}>
<ContentCard title="Bond Breakdown">
<ContentCard title="Stake Breakdown">
<BondBreakdownTable />
</ContentCard>
</Grid>
+46 -63
View File
@@ -125,24 +125,6 @@ export const PageMixnodes: React.FC = () => {
</>
),
},
{
field: 'bond',
headerName: 'Bond',
renderHeader: () => <CustomColumnHeading headingTitle="Bond" />,
type: 'number',
headerClassName: 'MuiDataGrid-header-override',
width: 200,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={getCellStyles(theme, params.row)}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{currencyToString(params.value)}
</MuiLink>
),
},
{
field: 'location',
headerName: 'Location',
@@ -162,24 +144,6 @@ export const PageMixnodes: React.FC = () => {
</Button>
),
},
{
field: 'self_percentage',
headerName: 'Self %',
width: 110,
headerClassName: 'MuiDataGrid-header-override',
renderHeader: () => <CustomColumnHeading headingTitle="Self %" />,
type: 'number',
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={getCellStyles(theme, params.row)}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{params.value}%
</MuiLink>
),
},
{
field: 'host',
headerName: 'Host',
@@ -198,19 +162,59 @@ export const PageMixnodes: React.FC = () => {
),
},
{
field: 'layer',
headerName: 'Layer',
renderHeader: () => <CustomColumnHeading headingTitle="Layer" />,
field: 'bond',
headerName: 'Stake',
renderHeader: () => <CustomColumnHeading headingTitle="Stake" />,
type: 'number',
headerClassName: 'MuiDataGrid-header-override',
width: 110,
width: 200,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={{ ...getCellStyles(theme, params.row), textAlign: 'left' }}
sx={getCellStyles(theme, params.row)}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{params.value}
{currencyToString(params.value)}
</MuiLink>
),
},
{
field: 'stake_saturation',
headerName: 'Stake Saturation',
renderHeader: () => <CustomColumnHeading headingTitle="Stake Saturation" />,
headerClassName: 'MuiDataGrid-header-override',
width: 175,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={{
textAlign: 'left',
color: params.value > 100 ? theme.palette.warning.main : 'inherit',
...getCellStyles(theme, params.row),
}}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{`${params.value.toFixed(2)} %`}
</MuiLink>
),
},
{
field: 'self_percentage',
headerName: 'Self %',
width: 110,
headerClassName: 'MuiDataGrid-header-override',
renderHeader: () => <CustomColumnHeading headingTitle="Self %" />,
type: 'number',
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={getCellStyles(theme, params.row)}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{params.value}%
</MuiLink>
),
},
@@ -248,27 +252,6 @@ export const PageMixnodes: React.FC = () => {
</MuiLink>
),
},
{
field: 'stake_saturation',
headerName: 'Stake Saturation',
renderHeader: () => <CustomColumnHeading headingTitle="Stake Saturation" />,
headerClassName: 'MuiDataGrid-header-override',
width: 175,
headerAlign: 'left',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={{
textAlign: 'left',
color: params.value > 100 ? theme.palette.warning.main : 'inherit',
...getCellStyles(theme, params.row),
}}
component={RRDLink}
to={`/network-components/mixnode/${params.row.identity_key}`}
>
{`${params.value.toFixed(2)} %`}
</MuiLink>
),
},
];
const handlePageSize = (event: SelectChangeEvent<string>) => {
+2 -1
View File
@@ -1,6 +1,7 @@
{
"packages": [
"ts-packages/*"
"ts-packages/*",
"nym-wallet"
],
"version": "0.0.0"
}
+1
View File
@@ -43,6 +43,7 @@ mixnode-common = { path="../common/mixnode-common" }
nonexhaustive-delayqueue = { path="../common/nonexhaustive-delayqueue" }
nymsphinx = { path="../common/nymsphinx" }
pemstore = { path="../common/pemstore" }
task = { path = "../common/task" }
topology = { path="../common/topology" }
validator-client = { path="../common/client-libs/validator-client" }
version-checker = { path="../common/version-checker" }
@@ -5,6 +5,7 @@ use crate::node::listener::connection_handler::packet_processing::{
MixProcessingResult, PacketProcessor,
};
use crate::node::packet_delayforwarder::PacketDelayForwardSender;
use crate::node::ShutdownListener;
use futures::StreamExt;
use log::{error, info};
use nymsphinx::forwarding::packet::MixPacket;
@@ -69,28 +70,40 @@ impl ConnectionHandler {
}
}
pub(crate) async fn handle_connection(self, conn: TcpStream, remote: SocketAddr) {
pub(crate) async fn handle_connection(
self,
conn: TcpStream,
remote: SocketAddr,
mut shutdown: ShutdownListener,
) {
debug!("Starting connection handler for {:?}", remote);
let mut framed_conn = Framed::new(conn, SphinxCodec);
while let Some(framed_sphinx_packet) = framed_conn.next().await {
match framed_sphinx_packet {
Ok(framed_sphinx_packet) => {
// TODO: benchmark spawning tokio task with full processing vs just processing it
// synchronously (without delaying inside of course,
// delay is moved to a global DelayQueue)
// under higher load in single and multi-threaded situation.
while !shutdown.is_shutdown() {
tokio::select! {
Some(framed_sphinx_packet) = framed_conn.next() => {
match framed_sphinx_packet {
Ok(framed_sphinx_packet) => {
// TODO: benchmark spawning tokio task with full processing vs just processing it
// synchronously (without delaying inside of course,
// delay is moved to a global DelayQueue)
// under higher load in single and multi-threaded situation.
// in theory we could process multiple sphinx packet from the same connection in parallel,
// but we already handle multiple concurrent connections so if anything, making
// that change would only slow things down
self.handle_received_packet(framed_sphinx_packet);
}
Err(err) => {
error!(
"The socket connection got corrupted with error: {:?}. Closing the socket",
err
);
return;
// in theory we could process multiple sphinx packet from the same connection in parallel,
// but we already handle multiple concurrent connections so if anything, making
// that change would only slow things down
self.handle_received_packet(framed_sphinx_packet);
}
Err(err) => {
error!(
"The socket connection got corrupted with error: {:?}. Closing the socket",
err
);
return;
}
}
},
_ = shutdown.recv() => {
log::trace!("ConnectionHandler: received shutdown");
}
}
}
@@ -99,5 +112,6 @@ impl ConnectionHandler {
"Closing connection from {:?}",
framed_conn.into_inner().peer_addr()
);
log::trace!("ConnectionHandler: Exiting");
}
}
+21 -9
View File
@@ -8,18 +8,22 @@ use std::process;
use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use super::ShutdownListener;
pub(crate) mod connection_handler;
pub(crate) struct Listener {
address: SocketAddr,
shutdown: ShutdownListener,
}
impl Listener {
pub(crate) fn new(address: SocketAddr) -> Self {
Listener { address }
pub(crate) fn new(address: SocketAddr, shutdown: ShutdownListener) -> Self {
Listener { address, shutdown }
}
async fn run(&mut self, connection_handler: ConnectionHandler) {
log::trace!("Starting Listener");
let listener = match TcpListener::bind(self.address).await {
Ok(listener) => listener,
Err(err) => {
@@ -28,15 +32,23 @@ impl Listener {
}
};
loop {
match listener.accept().await {
Ok((socket, remote_addr)) => {
let handler = connection_handler.clone();
tokio::spawn(handler.handle_connection(socket, remote_addr));
while !self.shutdown.is_shutdown() {
tokio::select! {
connection = listener.accept() => {
match connection {
Ok((socket, remote_addr)) => {
let handler = connection_handler.clone();
tokio::spawn(handler.handle_connection(socket, remote_addr, self.shutdown.clone()));
}
Err(err) => warn!("Failed to accept incoming connection - {:?}", err),
}
},
_ = self.shutdown.recv() => {
log::trace!("Listener: Received shutdown");
}
Err(err) => warn!("Failed to accept incoming connection - {:?}", err),
}
};
}
log::trace!("Listener: Exiting");
}
pub(crate) fn start(mut self, connection_handler: ConnectionHandler) -> JoinHandle<()> {
+40 -11
View File
@@ -25,6 +25,7 @@ use rand::thread_rng;
use std::net::SocketAddr;
use std::process;
use std::sync::Arc;
use task::{ShutdownListener, ShutdownNotifier};
use version_checker::parse_version;
mod http;
@@ -149,11 +150,15 @@ impl MixNode {
});
}
fn start_node_stats_controller(&self) -> (SharedNodeStats, node_statistics::UpdateSender) {
fn start_node_stats_controller(
&self,
shutdown: ShutdownListener,
) -> (SharedNodeStats, node_statistics::UpdateSender) {
info!("Starting node stats controller...");
let controller = node_statistics::Controller::new(
self.config.get_node_stats_logging_delay(),
self.config.get_node_stats_updating_delay(),
shutdown,
);
let node_stats_pointer = controller.get_node_stats_data_pointer();
let update_sender = controller.start();
@@ -165,6 +170,7 @@ impl MixNode {
&self,
node_stats_update_sender: node_statistics::UpdateSender,
delay_forwarding_channel: PacketDelayForwardSender,
shutdown: ShutdownListener,
) {
info!("Starting socket listener...");
@@ -178,12 +184,13 @@ impl MixNode {
self.config.get_mix_port(),
);
Listener::new(listening_address).start(connection_handler);
Listener::new(listening_address, shutdown).start(connection_handler);
}
fn start_packet_delay_forwarder(
&mut self,
node_stats_update_sender: node_statistics::UpdateSender,
shutdown: ShutdownListener,
) -> PacketDelayForwardSender {
info!("Starting packet delay-forwarder...");
@@ -197,6 +204,7 @@ impl MixNode {
let mut packet_forwarder = DelayForwarder::new(
mixnet_client::Client::new(client_config),
node_stats_update_sender,
shutdown,
);
let packet_sender = packet_forwarder.sender();
@@ -259,7 +267,10 @@ impl MixNode {
let existing_nodes = match validator_client.get_cached_mixnodes().await {
Ok(nodes) => nodes,
Err(err) => {
error!("failed to grab initial network mixnodes - {}\n Please try to startup again in few minutes", err);
error!(
"failed to grab initial network mixnodes - {err}\n \
Please try to startup again in few minutes",
);
process::exit(1);
}
};
@@ -272,16 +283,26 @@ impl MixNode {
.map(|node| node.mix_node.identity_key.clone())
}
async fn wait_for_interrupt(&self) {
async fn wait_for_interrupt(&self, mut shutdown: ShutdownNotifier) {
if let Err(e) = tokio::signal::ctrl_c().await {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
"There was an error while capturing SIGINT - {:?}. \
We will terminate regardless",
e
);
}
println!(
"Received SIGINT - the mixnode will terminate now (threads are not yet nicely stopped, if you see stack traces that's alright)."
"Received SIGINT - the mixnode will terminate now \
(threads are not yet nicely stopped, if you see stack traces that's alright)."
);
log::info!("Sending shutdown");
shutdown.signal_shutdown().ok();
log::info!("Waiting for tasks to finish... (Press ctrl-c to force)");
shutdown.wait_for_shutdown().await;
log::info!("Stopping nym mixnode");
}
pub async fn run(&mut self) {
@@ -299,15 +320,23 @@ impl MixNode {
}
}
let (node_stats_pointer, node_stats_update_sender) = self.start_node_stats_controller();
let delay_forwarding_channel =
self.start_packet_delay_forwarder(node_stats_update_sender.clone());
self.start_socket_listener(node_stats_update_sender, delay_forwarding_channel);
let shutdown = ShutdownNotifier::default();
let (node_stats_pointer, node_stats_update_sender) =
self.start_node_stats_controller(shutdown.subscribe());
let delay_forwarding_channel = self
.start_packet_delay_forwarder(node_stats_update_sender.clone(), shutdown.subscribe());
self.start_socket_listener(
node_stats_update_sender,
delay_forwarding_channel,
shutdown.subscribe(),
);
// TODO: these two also needs to be shutdown
let atomic_verloc_results = self.start_verloc_measurements();
self.start_http_api(atomic_verloc_results, node_stats_pointer);
info!("Finished nym mixnode startup procedure - it should now be able to receive mix traffic!");
self.wait_for_interrupt().await
self.wait_for_interrupt(shutdown).await
}
}
+72 -21
View File
@@ -9,6 +9,8 @@ use std::sync::Arc;
use std::time::{Duration, SystemTime};
use tokio::sync::{RwLock, RwLockReadGuard};
use super::ShutdownListener;
// convenience aliases
type PacketsMap = HashMap<String, u64>;
type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>;
@@ -209,28 +211,45 @@ impl CurrentPacketData {
struct UpdateHandler {
current_data: CurrentPacketData,
update_receiver: PacketDataReceiver,
shutdown: ShutdownListener,
}
impl UpdateHandler {
fn new(current_data: CurrentPacketData, update_receiver: PacketDataReceiver) -> Self {
fn new(
current_data: CurrentPacketData,
update_receiver: PacketDataReceiver,
shutdown: ShutdownListener,
) -> Self {
UpdateHandler {
current_data,
update_receiver,
shutdown,
}
}
async fn run(&mut self) {
while let Some(packet_data) = self.update_receiver.next().await {
match packet_data {
PacketEvent::Received => self.current_data.increment_received(),
PacketEvent::Sent(destination) => {
self.current_data.increment_sent(destination).await
log::trace!("Starting UpdateHandler");
while !self.shutdown.is_shutdown() {
tokio::select! {
Some(packet_data) = self.update_receiver.next() => {
match packet_data {
PacketEvent::Received => self.current_data.increment_received(),
PacketEvent::Sent(destination) => {
self.current_data.increment_sent(destination).await
}
PacketEvent::Dropped(destination) => {
self.current_data.increment_dropped(destination).await
}
}
}
PacketEvent::Dropped(destination) => {
self.current_data.increment_dropped(destination).await
_ = self.shutdown.recv() => {
log::trace!("UpdateHandler: Received shutdown");
break;
}
}
}
log::trace!("UpdateHandler: Exiting");
}
}
@@ -274,6 +293,7 @@ struct StatsUpdater {
updating_delay: Duration,
current_packet_data: CurrentPacketData,
current_stats: SharedNodeStats,
shutdown: ShutdownListener,
}
impl StatsUpdater {
@@ -281,11 +301,13 @@ impl StatsUpdater {
updating_delay: Duration,
current_packet_data: CurrentPacketData,
current_stats: SharedNodeStats,
shutdown: ShutdownListener,
) -> Self {
StatsUpdater {
updating_delay,
current_packet_data,
current_stats,
shutdown,
}
}
@@ -295,11 +317,16 @@ impl StatsUpdater {
self.current_stats.update(received, sent, dropped).await;
}
async fn run(&self) {
loop {
tokio::time::sleep(self.updating_delay).await;
self.update_stats().await
async fn run(&mut self) {
while !self.shutdown.is_shutdown() {
tokio::select! {
_ = tokio::time::sleep(self.updating_delay) => self.update_stats().await,
_ = self.shutdown.recv() => {
log::trace!("StatsUpdater: Received shutdown");
}
}
}
log::trace!("StatsUpdater: Exiting");
}
}
@@ -308,13 +335,15 @@ impl StatsUpdater {
struct PacketStatsConsoleLogger {
logging_delay: Duration,
stats: SharedNodeStats,
shutdown: ShutdownListener,
}
impl PacketStatsConsoleLogger {
fn new(logging_delay: Duration, stats: SharedNodeStats) -> Self {
fn new(logging_delay: Duration, stats: SharedNodeStats, shutdown: ShutdownListener) -> Self {
PacketStatsConsoleLogger {
logging_delay,
stats,
shutdown,
}
}
@@ -387,10 +416,16 @@ impl PacketStatsConsoleLogger {
}
async fn run(&mut self) {
loop {
tokio::time::sleep(self.logging_delay).await;
self.log_running_stats().await;
log::trace!("Starting PacketStatsConsoleLogger");
while !self.shutdown.is_shutdown() {
tokio::select! {
_ = tokio::time::sleep(self.logging_delay) => self.log_running_stats().await,
_ = self.shutdown.recv() => {
log::trace!("PacketStatsConsoleLogger: Received shutdown");
}
};
}
log::trace!("PacketStatsConsoleLogger: Exiting");
}
}
@@ -413,19 +448,32 @@ pub struct Controller {
}
impl Controller {
pub(crate) fn new(logging_delay: Duration, stats_updating_delay: Duration) -> Self {
pub(crate) fn new(
logging_delay: Duration,
stats_updating_delay: Duration,
shutdown: ShutdownListener,
) -> Self {
let (sender, receiver) = mpsc::unbounded();
let shared_packet_data = CurrentPacketData::new();
let shared_node_stats = SharedNodeStats::new();
Controller {
update_handler: UpdateHandler::new(shared_packet_data.clone(), receiver),
update_handler: UpdateHandler::new(
shared_packet_data.clone(),
receiver,
shutdown.clone(),
),
update_sender: UpdateSender::new(sender),
console_logger: PacketStatsConsoleLogger::new(logging_delay, shared_node_stats.clone()),
console_logger: PacketStatsConsoleLogger::new(
logging_delay,
shared_node_stats.clone(),
shutdown.clone(),
),
stats_updater: StatsUpdater::new(
stats_updating_delay,
shared_packet_data,
shared_node_stats.clone(),
shutdown,
),
node_stats: shared_node_stats,
}
@@ -441,7 +489,7 @@ impl Controller {
pub(crate) fn start(self) -> UpdateSender {
// move out of self
let mut update_handler = self.update_handler;
let stats_updater = self.stats_updater;
let mut stats_updater = self.stats_updater;
let mut console_logger = self.console_logger;
tokio::spawn(async move { update_handler.run().await });
@@ -455,12 +503,15 @@ impl Controller {
#[cfg(test)]
mod tests {
use super::*;
use task::ShutdownNotifier;
#[tokio::test]
async fn node_stats_reported_are_received() {
let logging_delay = Duration::from_millis(20);
let stats_updating_delay = Duration::from_millis(10);
let node_stats_controller = Controller::new(logging_delay, stats_updating_delay);
let shutdown = ShutdownNotifier::default();
let node_stats_controller =
Controller::new(logging_delay, stats_updating_delay, shutdown.subscribe());
let node_stats_pointer = node_stats_controller.get_node_stats_data_pointer();
let update_sender = node_stats_controller.start();

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