Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28177d5d5d | |||
| 10b63f8667 | |||
| 9989c226ae | |||
| 31f85e61f0 | |||
| 73ac5eb19b | |||
| f1f06ceca2 | |||
| f5841b2b60 | |||
| 413ef2e11a | |||
| 96a4e8b636 | |||
| 4e79ef1b12 | |||
| b5956933d9 | |||
| 765589c444 | |||
| 38663e41c3 | |||
| 1463ddd339 | |||
| d9a2e87fc6 | |||
| 4630eb6cd4 | |||
| aa00711138 | |||
| 6b3292ddbc | |||
| a5214af0df | |||
| 34d25f4faf | |||
| 54e024962c | |||
| e552ebb736 | |||
| 39aa3b624f | |||
| 2d2121b331 |
@@ -8,6 +8,11 @@ on:
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
enable_wireguard:
|
||||
description: "Add --features wireguard"
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
enable_deb:
|
||||
description: "True to enable cargo-deb installation and .deb package building"
|
||||
required: false
|
||||
@@ -65,6 +70,9 @@ jobs:
|
||||
- name: Set CARGO_FEATURES
|
||||
run: |
|
||||
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
|
||||
if: >
|
||||
github.event_name == 'schedule' ||
|
||||
(github.event_name == 'workflow_dispatch' && inputs.enable_wireguard == true)
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
|
||||
@@ -51,10 +51,6 @@ jobs:
|
||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
|
||||
|
||||
- name: Set CARGO_FEATURES
|
||||
run: |
|
||||
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@@ -64,8 +60,8 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --workspace --release ${{ env.CARGO_FEATURES }}
|
||||
|
||||
args: --workspace --release
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
+1
-38
@@ -4,44 +4,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2024.9-topdeck] (2024-07-26)
|
||||
|
||||
- chore: fix 1.80 lint issues ([#4731])
|
||||
- Handle clients with different versions in IPR ([#4723])
|
||||
- Add 1GB/day/user bandwidth cap ([#4717])
|
||||
- Feature/merge back ([#4710])
|
||||
- removed mixnode/gateway config migration code and disabled cli without explicit flag ([#4706])
|
||||
|
||||
[#4731]: https://github.com/nymtech/nym/pull/4731
|
||||
[#4723]: https://github.com/nymtech/nym/pull/4723
|
||||
[#4717]: https://github.com/nymtech/nym/pull/4717
|
||||
[#4710]: https://github.com/nymtech/nym/pull/4710
|
||||
[#4706]: https://github.com/nymtech/nym/pull/4706
|
||||
|
||||
## [2024.8-wispa] (2024-07-10)
|
||||
|
||||
- add event parsing to support cosmos_sdk > 0.50 ([#4697])
|
||||
- Fix NR config compatibility ([#4690])
|
||||
- Remove UserAgent constructor since it's weakly typed ([#4689])
|
||||
- [bugfix]: Node_api_check CLI looked over roles on blacklisted nodes ([#4687])
|
||||
- Add mixnodes to self describing api cache ([#4684])
|
||||
- Move and whole bump of crates to workspace and upgrade some ([#4680])
|
||||
- Remove code that refers to removed nym-network-statistics ([#4679])
|
||||
- Remove nym-network-statistics ([#4678])
|
||||
- Create UserAgent that can be passed from the binary to the nym api client ([#4677])
|
||||
- Add authenticator ([#4667])
|
||||
|
||||
[#4697]: https://github.com/nymtech/nym/pull/4697
|
||||
[#4690]: https://github.com/nymtech/nym/pull/4690
|
||||
[#4689]: https://github.com/nymtech/nym/pull/4689
|
||||
[#4687]: https://github.com/nymtech/nym/pull/4687
|
||||
[#4684]: https://github.com/nymtech/nym/pull/4684
|
||||
[#4680]: https://github.com/nymtech/nym/pull/4680
|
||||
[#4679]: https://github.com/nymtech/nym/pull/4679
|
||||
[#4678]: https://github.com/nymtech/nym/pull/4678
|
||||
[#4677]: https://github.com/nymtech/nym/pull/4677
|
||||
[#4667]: https://github.com/nymtech/nym/pull/4667
|
||||
|
||||
## [2024.7-doubledecker] (2024-07-04)
|
||||
|
||||
- Add an early return in `parse_raw_str_logs` for empty raw log strings. ([#4686])
|
||||
@@ -551,6 +513,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
[#3187]: https://github.com/nymtech/nym/issues/3187
|
||||
[#3203]: https://github.com/nymtech/nym/pull/3203
|
||||
[#3199]: https://github.com/nymtech/nym/pull/3199
|
||||
>>>>>>> master
|
||||
|
||||
## [v1.1.13] (2023-03-15)
|
||||
|
||||
|
||||
Generated
+31
-70
@@ -1471,7 +1471,7 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio 0.8.11",
|
||||
"mio",
|
||||
"parking_lot 0.12.3",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
@@ -1487,7 +1487,7 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio 0.8.11",
|
||||
"mio",
|
||||
"parking_lot 0.12.3",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
@@ -2240,7 +2240,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "explorer-api"
|
||||
version = "1.1.38"
|
||||
version = "1.1.36"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 4.5.7",
|
||||
@@ -3933,18 +3933,6 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.9",
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mix-fetch-wasm"
|
||||
version = "1.3.0-rc.0"
|
||||
@@ -4126,7 +4114,7 @@ dependencies = [
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"mio 0.8.11",
|
||||
"mio",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
@@ -4204,7 +4192,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.42"
|
||||
version = "1.1.40"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -4294,10 +4282,10 @@ dependencies = [
|
||||
"nym-ecash-time",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-node-requests",
|
||||
"nym-serde-helpers",
|
||||
"rocket",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde-helpers",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"tendermint 0.37.0",
|
||||
@@ -4325,7 +4313,6 @@ dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"bytes",
|
||||
"clap 4.5.7",
|
||||
"defguard_wireguard_rs",
|
||||
"fastrand 2.1.0",
|
||||
"futures",
|
||||
"ipnetwork 0.16.0",
|
||||
@@ -4425,7 +4412,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.40"
|
||||
version = "1.1.38"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -4504,7 +4491,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.37"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.7",
|
||||
@@ -4563,7 +4550,6 @@ dependencies = [
|
||||
"nym-config",
|
||||
"nym-country-group",
|
||||
"nym-credential-storage",
|
||||
"nym-credentials-interface",
|
||||
"nym-crypto",
|
||||
"nym-ecash-time",
|
||||
"nym-explorer-client",
|
||||
@@ -4810,10 +4796,10 @@ dependencies = [
|
||||
"log",
|
||||
"nym-bandwidth-controller",
|
||||
"nym-client-core",
|
||||
"nym-compact-ecash",
|
||||
"nym-config",
|
||||
"nym-credential-storage",
|
||||
"nym-credentials",
|
||||
"nym-credentials-interface",
|
||||
"nym-ecash-time",
|
||||
"nym-validator-client",
|
||||
"thiserror",
|
||||
@@ -4850,10 +4836,8 @@ dependencies = [
|
||||
"bls12_381",
|
||||
"nym-compact-ecash",
|
||||
"nym-ecash-time",
|
||||
"nym-network-defaults",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"strum 0.25.0",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
@@ -5013,7 +4997,6 @@ dependencies = [
|
||||
"nym-ecash-contract-common",
|
||||
"nym-ecash-double-spending",
|
||||
"nym-gateway-requests",
|
||||
"nym-gateway-storage",
|
||||
"nym-ip-packet-router",
|
||||
"nym-mixnet-client",
|
||||
"nym-mixnode-common",
|
||||
@@ -5103,24 +5086,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-gateway-storage"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bincode",
|
||||
"defguard_wireguard_rs",
|
||||
"log",
|
||||
"nym-credentials-interface",
|
||||
"nym-gateway-requests",
|
||||
"nym-sphinx",
|
||||
"sqlx",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-group-contract-common"
|
||||
version = "0.1.0"
|
||||
@@ -5412,7 +5377,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.40"
|
||||
version = "1.1.38"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -5463,7 +5428,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.1.6"
|
||||
version = "1.1.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bip39",
|
||||
@@ -5683,7 +5648,6 @@ dependencies = [
|
||||
"nym-credential-storage",
|
||||
"nym-credential-utils",
|
||||
"nym-credentials",
|
||||
"nym-credentials-interface",
|
||||
"nym-crypto",
|
||||
"nym-gateway-requests",
|
||||
"nym-network-defaults",
|
||||
@@ -5709,15 +5673,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-serde-helpers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bs58 0.5.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-service-providers-common"
|
||||
version = "0.1.0"
|
||||
@@ -5737,7 +5692,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.37"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.7",
|
||||
@@ -6162,14 +6117,12 @@ dependencies = [
|
||||
"nym-compact-ecash",
|
||||
"nym-config",
|
||||
"nym-credentials",
|
||||
"nym-credentials-interface",
|
||||
"nym-crypto",
|
||||
"nym-ecash-time",
|
||||
"nym-network-defaults",
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"nyxd-scraper",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"sha2 0.10.8",
|
||||
@@ -6220,14 +6173,12 @@ name = "nym-wireguard"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bincode",
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"defguard_wireguard_rs",
|
||||
"ip_network",
|
||||
"log",
|
||||
"nym-crypto",
|
||||
"nym-gateway-storage",
|
||||
"nym-network-defaults",
|
||||
"nym-task",
|
||||
"nym-wireguard-types",
|
||||
@@ -6242,6 +6193,7 @@ name = "nym-wireguard-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"dashmap",
|
||||
"hmac",
|
||||
"log",
|
||||
"nym-config",
|
||||
@@ -6258,7 +6210,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.5"
|
||||
version = "0.1.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -7962,6 +7914,15 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-helpers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bs58 0.5.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-json-wasm"
|
||||
version = "0.5.0"
|
||||
@@ -8218,7 +8179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio 0.8.11",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
@@ -9065,21 +9026,22 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.39.2"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio 1.0.1",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot 0.12.3",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9094,9 +9056,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -10076,7 +10038,6 @@ dependencies = [
|
||||
name = "wasm-utils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"futures",
|
||||
"getrandom",
|
||||
"gloo-net",
|
||||
|
||||
+8
-9
@@ -52,8 +52,6 @@ members = [
|
||||
"common/ecash-time",
|
||||
"common/execute",
|
||||
"common/exit-policy",
|
||||
"common/gateway-requests",
|
||||
"common/gateway-storage",
|
||||
"common/http-api-client",
|
||||
"common/http-api-common",
|
||||
"common/inclusion-probability",
|
||||
@@ -98,6 +96,7 @@ members = [
|
||||
"explorer-api/explorer-api-requests",
|
||||
"explorer-api/explorer-client",
|
||||
"gateway",
|
||||
"gateway/gateway-requests",
|
||||
"integrations/bity",
|
||||
"mixnode",
|
||||
"sdk/lib/socks5-listener",
|
||||
@@ -140,7 +139,7 @@ default-members = [
|
||||
"tools/nymvisor",
|
||||
"explorer-api",
|
||||
"nym-validator-rewarder",
|
||||
"nym-node",
|
||||
"nym-node"
|
||||
]
|
||||
|
||||
exclude = [
|
||||
@@ -291,11 +290,11 @@ tar = "0.4.40"
|
||||
tempfile = "3.5.0"
|
||||
thiserror = "1.0.48"
|
||||
time = "0.3.30"
|
||||
tokio = "1.39"
|
||||
tokio-stream = "0.1.15"
|
||||
tokio-test = "0.4.4"
|
||||
tokio = "1.33.0"
|
||||
tokio-stream = "0.1.14"
|
||||
tokio-test = "0.4.2"
|
||||
tokio-tungstenite = { version = "0.20.1" }
|
||||
tokio-util = "0.7.11"
|
||||
tokio-util = "0.7.10"
|
||||
toml = "0.8.14"
|
||||
tower = "0.4.13"
|
||||
tower-http = "0.5.2"
|
||||
@@ -347,8 +346,8 @@ bip32 = { version = "0.5.1", default-features = false }
|
||||
# plus response message parsing (which is, as of the time of writing this message, waiting to get merged)
|
||||
#cosmrs = { path = "../cosmos-rust-fork/cosmos-rust/cosmrs" }
|
||||
cosmrs = { git = "https://github.com/cosmos/cosmos-rust", rev = "4b1332e6d8258ac845cef71589c8d362a669675a" } # unfortuntely we need a fork by yours truly to get the staking support
|
||||
tendermint = "0.37.0" # same version as used by cosmrs
|
||||
tendermint-rpc = "0.37.0" # same version as used by cosmrs
|
||||
tendermint = "0.37.0" # same version as used by cosmrs
|
||||
tendermint-rpc = "0.37.0" # same version as used by cosmrs
|
||||
prost = { version = "0.12", default-features = false }
|
||||
|
||||
# wasm-related dependencies
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.37"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
@@ -26,46 +26,30 @@ clap = { workspace = true, features = ["cargo", "derive"] }
|
||||
dirs = { workspace = true }
|
||||
log = { workspace = true } # self explanatory
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = [
|
||||
"derive",
|
||||
] } # for config serialization/deserialization
|
||||
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tap = { workspace = true }
|
||||
time = { workspace = true }
|
||||
tokio = { workspace = true, features = [
|
||||
"rt-multi-thread",
|
||||
"net",
|
||||
"signal",
|
||||
] } # async runtime
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } # async runtime
|
||||
tokio-tungstenite = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
## internal
|
||||
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
|
||||
nym-bin-common = { path = "../../common/bin-common", features = [
|
||||
"output_format",
|
||||
"clap",
|
||||
] }
|
||||
nym-client-core = { path = "../../common/client-core", features = [
|
||||
"fs-credentials-storage",
|
||||
"fs-surb-storage",
|
||||
"fs-gateways-storage",
|
||||
"cli",
|
||||
] }
|
||||
nym-bin-common = { path = "../../common/bin-common", features = ["output_format", "clap"] }
|
||||
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] }
|
||||
nym-config = { path = "../../common/config" }
|
||||
nym-credential-storage = { path = "../../common/credential-storage" }
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-crypto = { path = "../../common/crypto" }
|
||||
nym-gateway-requests = { path = "../../common/gateway-requests" }
|
||||
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
nym-pemstore = { path = "../../common/pemstore" }
|
||||
nym-task = { path = "../../common/task" }
|
||||
nym-topology = { path = "../../common/topology" }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client", features = [
|
||||
"http-client",
|
||||
] }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] }
|
||||
nym-client-websocket-requests = { path = "websocket-requests" }
|
||||
nym-id = { path = "../../common/nym-id" }
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ impl Handler {
|
||||
) {
|
||||
// We don't want a crash in the connection handler to trigger a shutdown of the whole
|
||||
// process.
|
||||
task_client.disarm();
|
||||
task_client.mark_as_success();
|
||||
|
||||
let ws_stream = match accept_async(socket).await {
|
||||
Ok(ws_stream) => ws_stream,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.37"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
@@ -11,9 +11,7 @@ license.workspace = true
|
||||
bs58 = { workspace = true }
|
||||
clap = { workspace = true, features = ["cargo", "derive"] }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true, features = [
|
||||
"derive",
|
||||
] } # for config serialization/deserialization
|
||||
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
|
||||
serde_json = { workspace = true }
|
||||
tap = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
@@ -24,21 +22,13 @@ url = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
# internal
|
||||
nym-bin-common = { path = "../../common/bin-common", features = [
|
||||
"output_format",
|
||||
"clap",
|
||||
] }
|
||||
nym-client-core = { path = "../../common/client-core", features = [
|
||||
"fs-credentials-storage",
|
||||
"fs-surb-storage",
|
||||
"fs-gateways-storage",
|
||||
"cli",
|
||||
] }
|
||||
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
|
||||
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] }
|
||||
nym-config = { path = "../../common/config" }
|
||||
nym-credential-storage = { path = "../../common/credential-storage" }
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-crypto = { path = "../../common/crypto" }
|
||||
nym-gateway-requests = { path = "../../common/gateway-requests" }
|
||||
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
|
||||
nym-id = { path = "../../common/nym-id" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
|
||||
@@ -46,9 +36,7 @@ nym-pemstore = { path = "../../common/pemstore" }
|
||||
nym-socks5-client-core = { path = "../../common/socks5-client-core" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
nym-topology = { path = "../../common/topology" }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client", features = [
|
||||
"http-client",
|
||||
] }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -8,7 +8,6 @@ use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials::ecash::bandwidth::IssuanceTicketBook;
|
||||
use nym_credentials::ecash::utils::obtain_aggregate_wallet;
|
||||
use nym_credentials::IssuedTicketBook;
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_ecash_time::{ecash_default_expiration_date, Date};
|
||||
use nym_validator_client::coconut::all_ecash_api_clients;
|
||||
@@ -23,7 +22,6 @@ pub async fn make_deposit<C>(
|
||||
client: &C,
|
||||
client_id: &[u8],
|
||||
expiration: Option<Date>,
|
||||
ticketbook_type: TicketType,
|
||||
) -> Result<IssuanceTicketBook, BandwidthControllerError>
|
||||
where
|
||||
C: EcashSigningClient + EcashQueryClient + Sync,
|
||||
@@ -50,7 +48,6 @@ where
|
||||
deposit_id,
|
||||
client_id,
|
||||
signing_key,
|
||||
ticketbook_type,
|
||||
expiration,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ nym-country-group = { path = "../country-group" }
|
||||
nym-crypto = { path = "../crypto" }
|
||||
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
|
||||
nym-gateway-client = { path = "../client-libs/gateway-client" }
|
||||
nym-gateway-requests = { path = "../gateway-requests" }
|
||||
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
|
||||
nym-metrics = { path = "../nym-metrics" }
|
||||
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
@@ -46,12 +46,9 @@ nym-pemstore = { path = "../pemstore" }
|
||||
nym-topology = { path = "../topology", features = ["serializable"] }
|
||||
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
||||
nym-task = { path = "../task" }
|
||||
nym-credentials-interface = { path = "../credentials-interface" }
|
||||
nym-credential-storage = { path = "../credential-storage" }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-client-core-config-types = { path = "./config-types", features = [
|
||||
"disk-persistence",
|
||||
] }
|
||||
nym-client-core-config-types = { path = "./config-types", features = ["disk-persistence"] }
|
||||
nym-client-core-surb-storage = { path = "./surb-storage" }
|
||||
nym-client-core-gateways-storage = { path = "./gateways-storage" }
|
||||
nym-ecash-time = { path = "../ecash-time" }
|
||||
@@ -118,7 +115,6 @@ tempfile = { workspace = true }
|
||||
[features]
|
||||
default = []
|
||||
cli = ["clap", "comfy-table"]
|
||||
fs-credentials-storage = ["nym-credential-storage/persistent-storage"]
|
||||
fs-surb-storage = ["nym-client-core-surb-storage/fs-surb-storage"]
|
||||
fs-gateways-storage = ["nym-client-core-gateways-storage/fs-gateways-storage"]
|
||||
wasm = ["nym-gateway-client/wasm"]
|
||||
|
||||
@@ -18,7 +18,7 @@ url.workspace = true
|
||||
zeroize = { workspace = true, features = ["zeroize_derive"] }
|
||||
|
||||
nym-crypto = { path = "../../crypto", features = ["asymmetric"] }
|
||||
nym-gateway-requests = { path = "../../gateway-requests" }
|
||||
nym-gateway-requests = { path = "../../../gateway/gateway-requests" }
|
||||
|
||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
|
||||
workspace = true
|
||||
@@ -27,12 +27,7 @@ optional = true
|
||||
|
||||
[build-dependencies]
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
|
||||
|
||||
[features]
|
||||
fs-gateways-storage = ["sqlx"]
|
||||
fs-gateways-storage = ["sqlx"]
|
||||
@@ -5,15 +5,14 @@ use crate::cli_helpers::{CliClient, CliClientConfig};
|
||||
use crate::error::ClientCoreError;
|
||||
use nym_credential_storage::models::BasicTicketbookInformation;
|
||||
use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_ecash_time::ecash_today;
|
||||
use nym_network_defaults::TicketbookType::MixnetEntry;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::Date;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct AvailableTicketbook {
|
||||
pub id: i64,
|
||||
pub typ: TicketType,
|
||||
pub expiration: Date,
|
||||
pub issued_tickets: u32,
|
||||
pub claimed_tickets: u32,
|
||||
@@ -46,7 +45,6 @@ impl AvailableTicketbook {
|
||||
|
||||
vec![
|
||||
comfy_table::Cell::new(self.id.to_string()),
|
||||
comfy_table::Cell::new(self.typ),
|
||||
expiration,
|
||||
comfy_table::Cell::new(format!("{issued} ({si_issued})")),
|
||||
comfy_table::Cell::new(format!("{claimed} ({si_claimed})")),
|
||||
@@ -57,22 +55,17 @@ impl AvailableTicketbook {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<BasicTicketbookInformation> for AvailableTicketbook {
|
||||
type Error = ClientCoreError;
|
||||
|
||||
fn try_from(value: BasicTicketbookInformation) -> Result<Self, Self::Error> {
|
||||
let typ = value
|
||||
.ticketbook_type
|
||||
.parse()
|
||||
.map_err(|_| ClientCoreError::UnknownTicketType)?;
|
||||
Ok(AvailableTicketbook {
|
||||
impl From<BasicTicketbookInformation> for AvailableTicketbook {
|
||||
fn from(value: BasicTicketbookInformation) -> Self {
|
||||
AvailableTicketbook {
|
||||
id: value.id,
|
||||
typ,
|
||||
expiration: value.expiration_date,
|
||||
issued_tickets: value.total_tickets,
|
||||
claimed_tickets: value.used_tickets,
|
||||
ticket_size: typ.to_repr().bandwidth_value(),
|
||||
})
|
||||
|
||||
// TODO: this will change when 'type' field is introduced; for now doesn't matter what we put there
|
||||
ticket_size: MixnetEntry.bandwidth_value(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +79,6 @@ impl std::fmt::Display for AvailableTicketbooks {
|
||||
let mut table = comfy_table::Table::new();
|
||||
table.set_header(vec![
|
||||
"id",
|
||||
"type",
|
||||
"expiration",
|
||||
"issued tickets (bandwidth)",
|
||||
"claimed tickets (bandwidth)",
|
||||
@@ -132,9 +124,6 @@ where
|
||||
})?;
|
||||
|
||||
Ok(AvailableTicketbooks(
|
||||
ticketbooks
|
||||
.into_iter()
|
||||
.map(TryInto::<AvailableTicketbook>::try_into)
|
||||
.collect::<Result<_, _>>()?,
|
||||
ticketbooks.into_iter().map(Into::into).collect(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ where
|
||||
Err(ClientCoreError::CustomGatewaySelectionExpected)
|
||||
} else {
|
||||
// and make sure to invalidate the task client so we wouldn't cause premature shutdown
|
||||
shutdown.disarm();
|
||||
shutdown.mark_as_success();
|
||||
custom_gateway_transceiver.set_packet_router(packet_router)?;
|
||||
Ok(custom_gateway_transceiver)
|
||||
};
|
||||
@@ -562,7 +562,7 @@ where
|
||||
if topology_config.disable_refreshing {
|
||||
// if we're not spawning the refresher, don't cause shutdown immediately
|
||||
info!("The topology refesher is not going to be started");
|
||||
shutdown.disarm();
|
||||
shutdown.mark_as_success();
|
||||
} else {
|
||||
// don't spawn the refresher if we don't want to be refreshing the topology.
|
||||
// only use the initial values obtained
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::{
|
||||
config::{self, disk_persistence::CommonClientPaths},
|
||||
error::ClientCoreError,
|
||||
};
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-credentials-storage"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage;
|
||||
|
||||
pub use nym_client_core_gateways_storage as gateways_storage;
|
||||
|
||||
@@ -474,6 +474,13 @@ where
|
||||
Poll::Ready(Some((real_messages, conn_id))) => {
|
||||
log::trace!("handling real_messages: size: {}", real_messages.len());
|
||||
|
||||
// This is the last step in the pipeline where we know the type of the message, so
|
||||
// lets count the number of retransmissions here.
|
||||
if conn_id == TransmissionLane::Retransmission {
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RetransmissionQueued);
|
||||
}
|
||||
|
||||
// First store what we got for the given connection id
|
||||
self.transmission_buffer.store(&conn_id, real_messages);
|
||||
let real_next = self.pop_next_message().expect("we just added one");
|
||||
|
||||
@@ -68,9 +68,6 @@ pub enum ClientCoreError {
|
||||
source: Box<dyn Error + Send + Sync>,
|
||||
},
|
||||
|
||||
#[error("the provided ticket type is invalid")]
|
||||
UnknownTicketType,
|
||||
|
||||
#[error("the gateway id is invalid - {0}")]
|
||||
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
||||
|
||||
|
||||
@@ -46,34 +46,13 @@ const MEASUREMENTS: usize = 3;
|
||||
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
|
||||
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
|
||||
|
||||
// The abstraction that some of these helpers use
|
||||
pub trait ConnectableGateway {
|
||||
fn identity(&self) -> &identity::PublicKey;
|
||||
fn clients_address(&self) -> String;
|
||||
fn is_wss(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ConnectableGateway for gateway::Node {
|
||||
fn identity(&self) -> &identity::PublicKey {
|
||||
self.identity()
|
||||
}
|
||||
|
||||
fn clients_address(&self) -> String {
|
||||
self.clients_address()
|
||||
}
|
||||
|
||||
fn is_wss(&self) -> bool {
|
||||
self.clients_wss_port.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
struct GatewayWithLatency<'a, G: ConnectableGateway> {
|
||||
gateway: &'a G,
|
||||
struct GatewayWithLatency<'a> {
|
||||
gateway: &'a gateway::Node,
|
||||
latency: Duration,
|
||||
}
|
||||
|
||||
impl<'a, G: ConnectableGateway> GatewayWithLatency<'a, G> {
|
||||
fn new(gateway: &'a G, latency: Duration) -> Self {
|
||||
impl<'a> GatewayWithLatency<'a> {
|
||||
fn new(gateway: &'a gateway::Node, latency: Duration) -> Self {
|
||||
GatewayWithLatency { gateway, latency }
|
||||
}
|
||||
}
|
||||
@@ -151,14 +130,11 @@ async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
|
||||
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
|
||||
}
|
||||
|
||||
async fn measure_latency<G>(gateway: &G) -> Result<GatewayWithLatency<G>, ClientCoreError>
|
||||
where
|
||||
G: ConnectableGateway,
|
||||
{
|
||||
async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
|
||||
let addr = gateway.clients_address();
|
||||
trace!(
|
||||
"establishing connection to {} ({addr})...",
|
||||
gateway.identity(),
|
||||
gateway.identity_key,
|
||||
);
|
||||
let mut stream = connect(&addr).await?;
|
||||
|
||||
@@ -201,7 +177,7 @@ where
|
||||
let count = results.len() as u64;
|
||||
if count == 0 {
|
||||
return Err(ClientCoreError::NoGatewayMeasurements {
|
||||
identity: gateway.identity().to_base58_string(),
|
||||
identity: gateway.identity_key.to_base58_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -211,11 +187,11 @@ where
|
||||
Ok(GatewayWithLatency::new(gateway, avg))
|
||||
}
|
||||
|
||||
pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone>(
|
||||
pub async fn choose_gateway_by_latency<R: Rng>(
|
||||
rng: &mut R,
|
||||
gateways: &[G],
|
||||
gateways: &[gateway::Node],
|
||||
must_use_tls: bool,
|
||||
) -> Result<G, ClientCoreError> {
|
||||
) -> Result<gateway::Node, ClientCoreError> {
|
||||
let gateways = filter_by_tls(gateways, must_use_tls)?;
|
||||
|
||||
info!(
|
||||
@@ -247,19 +223,21 @@ pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone
|
||||
|
||||
info!(
|
||||
"chose gateway {} with average latency of {:?}",
|
||||
chosen.gateway.identity(),
|
||||
chosen.latency
|
||||
chosen.gateway.identity_key, chosen.latency
|
||||
);
|
||||
|
||||
Ok(chosen.gateway.clone())
|
||||
}
|
||||
|
||||
fn filter_by_tls<G: ConnectableGateway>(
|
||||
gateways: &[G],
|
||||
fn filter_by_tls(
|
||||
gateways: &[gateway::Node],
|
||||
must_use_tls: bool,
|
||||
) -> Result<Vec<&G>, ClientCoreError> {
|
||||
) -> Result<Vec<&gateway::Node>, ClientCoreError> {
|
||||
if must_use_tls {
|
||||
let filtered = gateways.iter().filter(|g| g.is_wss()).collect::<Vec<_>>();
|
||||
let filtered = gateways
|
||||
.iter()
|
||||
.filter(|g| g.clients_wss_port.is_some())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if filtered.is_empty() {
|
||||
return Err(ClientCoreError::NoWssGateways);
|
||||
|
||||
@@ -2,9 +2,7 @@ use std::future::Future;
|
||||
|
||||
#[cfg(all(
|
||||
not(target_arch = "wasm32"),
|
||||
feature = "cli",
|
||||
feature = "fs-surb-storage",
|
||||
feature = "fs-credentials-storage",
|
||||
feature = "fs-gateways-storage"
|
||||
))]
|
||||
pub mod cli_helpers;
|
||||
|
||||
@@ -24,7 +24,7 @@ nym-bandwidth-controller = { path = "../../bandwidth-controller" }
|
||||
nym-credentials = { path = "../../credentials" }
|
||||
nym-credential-storage = { path = "../../credential-storage" }
|
||||
nym-crypto = { path = "../../crypto" }
|
||||
nym-gateway-requests = { path = "../../gateway-requests" }
|
||||
nym-gateway-requests = { path = "../../../gateway/gateway-requests" }
|
||||
nym-network-defaults = { path = "../../network-defaults" }
|
||||
nym-sphinx = { path = "../../nymsphinx" }
|
||||
nym-pemstore = { path = "../../pemstore" }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::GatewayClientError;
|
||||
use nym_network_defaults::TicketTypeRepr::V1MixnetEntry;
|
||||
use nym_network_defaults::TicketbookType::MixnetEntry;
|
||||
use si_scale::helpers::bibytes2;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -103,7 +103,7 @@ impl BandwidthTickets {
|
||||
|
||||
// 20% of entry ticket value
|
||||
pub const DEFAULT_REMAINING_BANDWIDTH_THRESHOLD: i64 =
|
||||
(V1MixnetEntry.bandwidth_value() / 5) as i64;
|
||||
(MixnetEntry.bandwidth_value() / 5) as i64;
|
||||
|
||||
pub const DEFAULT_CUTOFF_REMAINING_BANDWIDTH_THRESHOLD: Option<i64> = None;
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ impl PacketRouter {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn disarm(&mut self) {
|
||||
self.shutdown.disarm();
|
||||
pub fn mark_as_success(&mut self) {
|
||||
self.shutdown.mark_as_success();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ impl PartiallyDelegatedRouter {
|
||||
let return_res = match ret {
|
||||
Err(err) => self.stream_return.send(Err(err)),
|
||||
Ok(_) => {
|
||||
self.packet_router.disarm();
|
||||
task_client.disarm();
|
||||
self.packet_router.mark_as_success();
|
||||
task_client.mark_as_success();
|
||||
self.stream_return.send(Ok(split_stream))
|
||||
}
|
||||
};
|
||||
|
||||
@@ -23,8 +23,8 @@ use nym_api_requests::ecash::VerificationKeyResponse;
|
||||
pub use nym_api_requests::{
|
||||
ecash::{
|
||||
models::{
|
||||
EpochCredentialsResponse, IssuedCredentialResponse, IssuedCredentialsResponse,
|
||||
IssuedTicketbook, IssuedTicketbookBody, SpentCredentialsResponse,
|
||||
EpochCredentialsResponse, IssuedCredential, IssuedCredentialBody,
|
||||
IssuedCredentialResponse, IssuedCredentialsResponse, SpentCredentialsResponse,
|
||||
},
|
||||
BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody,
|
||||
PartialCoinIndicesSignatureResponse, PartialExpirationDateSignatureResponse,
|
||||
|
||||
@@ -683,24 +683,6 @@ pub trait MixnetSigningClient {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn migrate_vested_mixnode(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_mixnet_contract(fee, MixnetExecuteMsg::MigrateVestedMixNode {}, vec![])
|
||||
.await
|
||||
}
|
||||
|
||||
async fn migrate_vested_delegation(
|
||||
&self,
|
||||
mix_id: MixId,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_mixnet_contract(
|
||||
fee,
|
||||
MixnetExecuteMsg::MigrateVestedDelegation { mix_id },
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(feature = "contract-testing")]
|
||||
async fn testing_resolve_all_pending_events(
|
||||
&self,
|
||||
@@ -946,12 +928,6 @@ mod tests {
|
||||
MixnetExecuteMsg::WithdrawDelegatorRewardOnBehalf { mix_id, owner } => client
|
||||
.withdraw_delegator_reward_on_behalf(owner.parse().unwrap(), mix_id, None)
|
||||
.ignore(),
|
||||
MixnetExecuteMsg::MigrateVestedMixNode { .. } => {
|
||||
client.migrate_vested_mixnode(None).ignore()
|
||||
}
|
||||
MixnetExecuteMsg::MigrateVestedDelegation { mix_id } => {
|
||||
client.migrate_vested_delegation(mix_id, None).ignore()
|
||||
}
|
||||
|
||||
#[cfg(feature = "contract-testing")]
|
||||
MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => {
|
||||
|
||||
@@ -437,7 +437,6 @@ where
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
|
||||
use nym_vesting_contract_common::ExecuteMsg;
|
||||
|
||||
// it's enough that this compiles and clippy is happy about it
|
||||
#[allow(dead_code)]
|
||||
@@ -561,9 +560,6 @@ mod tests {
|
||||
VestingExecuteMsg::UpdateLockedPledgeCap { address, cap } => client
|
||||
.update_locked_pledge_cap(address.parse().unwrap(), cap, None)
|
||||
.ignore(),
|
||||
// those will never be manually called by clients
|
||||
ExecuteMsg::TrackMigratedMixnode { .. } => "explicitly_ignored".ignore(),
|
||||
ExecuteMsg::TrackMigratedDelegation { .. } => "explicitly_ignored".ignore(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TEMPORARY WORKAROUND:
|
||||
// those features are expected as the below should only get activated whenever
|
||||
// the corresponding features in tendermint-rpc are enabled transitively
|
||||
#![allow(unexpected_cfgs)]
|
||||
|
||||
use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient;
|
||||
use crate::nyxd::error::NyxdError;
|
||||
use crate::nyxd::{Config, GasPrice, Hash, Height};
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TEMPORARY WORKAROUND:
|
||||
// those features are expected as the below should only get activated whenever
|
||||
// the corresponding features in tendermint-rpc are enabled transitively
|
||||
#![allow(unexpected_cfgs)]
|
||||
|
||||
use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts};
|
||||
use crate::nyxd::cosmwasm_client::types::{
|
||||
ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult,
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TEMPORARY WORKAROUND:
|
||||
// those features are expected as the below should only get activated whenever
|
||||
// the corresponding features in tendermint-rpc are enabled transitively
|
||||
#![allow(unexpected_cfgs)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cosmrs::tendermint::{self, abci, block::Height, evidence::Evidence, Genesis, Hash};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
@@ -7,16 +7,11 @@ use anyhow::bail;
|
||||
use clap::Parser;
|
||||
use nym_credential_storage::initialise_persistent_storage;
|
||||
use nym_credential_utils::utils;
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
/// Specify which type of ticketbook should be issued
|
||||
#[clap(long, default_value_t = TicketType::default())]
|
||||
pub(crate) ticketbook_type: TicketType,
|
||||
|
||||
/// Config file of the client that is supposed to use the credential.
|
||||
#[clap(long)]
|
||||
pub(crate) client_config: PathBuf,
|
||||
@@ -44,13 +39,7 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
|
||||
|
||||
let persistent_storage = initialise_persistent_storage(credentials_store).await;
|
||||
let private_id_key: identity::PrivateKey = nym_pemstore::load_key(private_id_key)?;
|
||||
utils::issue_credential(
|
||||
&client,
|
||||
&persistent_storage,
|
||||
&private_id_key.to_bytes(),
|
||||
args.ticketbook_type,
|
||||
)
|
||||
.await?;
|
||||
utils::issue_credential(&client, &persistent_storage, &private_id_key.to_bytes()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use clap::Parser;
|
||||
use cosmwasm_std::Decimal;
|
||||
use log::{debug, info};
|
||||
use nym_mixnet_contract_common::{
|
||||
InitialRewardingParams, InstantiateMsg, OperatingCostRange, Percent, ProfitMarginRange,
|
||||
};
|
||||
use nym_network_defaults::mainnet::MIX_DENOM;
|
||||
use nym_network_defaults::TOTAL_SUPPLY;
|
||||
use nym_validator_client::nyxd::{AccountId, Coin};
|
||||
|
||||
use cosmwasm_std::Decimal;
|
||||
use nym_mixnet_contract_common::{InitialRewardingParams, InstantiateMsg, Percent};
|
||||
use nym_validator_client::nyxd::AccountId;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn default_maximum_operating_cost() -> Coin {
|
||||
Coin::new(TOTAL_SUPPLY, MIX_DENOM.base)
|
||||
}
|
||||
|
||||
pub fn default_minimum_operating_cost() -> Coin {
|
||||
Coin::new(0, MIX_DENOM.base)
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(long)]
|
||||
@@ -61,18 +50,6 @@ pub struct Args {
|
||||
|
||||
#[clap(long, default_value_t = 240)]
|
||||
pub active_set_size: u32,
|
||||
|
||||
#[clap(long, default_value_t = Percent::zero())]
|
||||
pub minimum_profit_margin_percent: Percent,
|
||||
|
||||
#[clap(long, default_value_t = Percent::hundred())]
|
||||
pub maximum_profit_margin_percent: Percent,
|
||||
|
||||
#[clap(long, default_value_t = default_minimum_operating_cost())]
|
||||
pub minimum_interval_operating_cost: Coin,
|
||||
|
||||
#[clap(long, default_value_t = default_maximum_operating_cost())]
|
||||
pub maximum_interval_operating_cost: Coin,
|
||||
}
|
||||
|
||||
pub async fn generate(args: Args) {
|
||||
@@ -120,10 +97,6 @@ pub async fn generate(args: Args) {
|
||||
.expect("Rewarding (mix) denom has to be set")
|
||||
});
|
||||
|
||||
if args.minimum_interval_operating_cost.denom != args.maximum_interval_operating_cost.denom {
|
||||
panic!("different denoms for operating cost bounds")
|
||||
}
|
||||
|
||||
let instantiate_msg = InstantiateMsg {
|
||||
rewarding_validator_address: rewarding_validator_address.to_string(),
|
||||
vesting_contract_address: vesting_contract_address.to_string(),
|
||||
@@ -131,14 +104,6 @@ pub async fn generate(args: Args) {
|
||||
epochs_in_interval: args.epochs_in_interval,
|
||||
epoch_duration: Duration::from_secs(args.epoch_duration),
|
||||
initial_rewarding_params,
|
||||
profit_margin: ProfitMarginRange {
|
||||
minimum: args.minimum_profit_margin_percent,
|
||||
maximum: args.maximum_profit_margin_percent,
|
||||
},
|
||||
interval_operating_cost: OperatingCostRange {
|
||||
minimum: args.minimum_interval_operating_cost.amount.into(),
|
||||
maximum: args.maximum_interval_operating_cost.amount.into(),
|
||||
},
|
||||
};
|
||||
|
||||
debug!("instantiate_msg: {:?}", instantiate_msg);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::SigningClient;
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_mixnet_contract_common::MixId;
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(long)]
|
||||
pub mix_id: Option<MixId>,
|
||||
|
||||
#[clap(long)]
|
||||
pub identity_key: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn migrate_vested_delegation(args: Args, client: SigningClient) {
|
||||
let mix_id = match args.mix_id {
|
||||
Some(mix_id) => mix_id,
|
||||
None => {
|
||||
let identity_key = args
|
||||
.identity_key
|
||||
.expect("either mix_id or mix_identity has to be specified");
|
||||
let node_details = client
|
||||
.get_mixnode_details_by_identity(identity_key)
|
||||
.await
|
||||
.expect("contract query failed")
|
||||
.mixnode_details
|
||||
.expect("mixnode with the specified identity doesnt exist");
|
||||
node_details.mix_id()
|
||||
}
|
||||
};
|
||||
|
||||
let res = client
|
||||
.migrate_vested_delegation(mix_id, None)
|
||||
.await
|
||||
.expect("failed to migrate delegation!");
|
||||
|
||||
info!("migration result: {:?}", res)
|
||||
}
|
||||
@@ -7,7 +7,6 @@ pub mod rewards;
|
||||
|
||||
pub mod delegate_to_mixnode;
|
||||
pub mod delegate_to_multiple_mixnodes;
|
||||
pub mod migrate_vested_delegation;
|
||||
pub mod query_for_delegations;
|
||||
pub mod undelegate_from_mixnode;
|
||||
pub mod vesting_delegate_to_mixnode;
|
||||
@@ -36,6 +35,4 @@ pub enum MixnetDelegatorsCommands {
|
||||
DelegateVesting(vesting_delegate_to_mixnode::Args),
|
||||
/// Undelegate from a mixnode (when originally using locked tokens)
|
||||
UndelegateVesting(vesting_undelegate_from_mixnode::Args),
|
||||
/// Migrate the delegation to use liquid tokens
|
||||
MigrateVestedDelegation(migrate_vested_delegation::Args),
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ async fn print_delegation_events(events: Vec<PendingEpochEvent>, client: &Signin
|
||||
mix_id,
|
||||
amount,
|
||||
proxy,
|
||||
..
|
||||
} => {
|
||||
if owner.as_str() == client.nyxd.address().as_ref() {
|
||||
table.add_row(vec![
|
||||
@@ -112,7 +111,6 @@ async fn print_delegation_events(events: Vec<PendingEpochEvent>, client: &Signin
|
||||
owner,
|
||||
mix_id,
|
||||
proxy,
|
||||
..
|
||||
} => {
|
||||
if owner.as_str() == client.nyxd.address().as_ref() {
|
||||
table.add_row(vec![
|
||||
|
||||
+13
-2
@@ -8,7 +8,7 @@ use cosmwasm_std::Coin;
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload;
|
||||
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
@@ -39,6 +39,10 @@ pub struct Args {
|
||||
)]
|
||||
pub amount: u128,
|
||||
|
||||
/// Indicates whether the gateway is going to get bonded via a vesting account
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
|
||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||
output: OutputFormat,
|
||||
}
|
||||
@@ -70,8 +74,15 @@ pub async fn create_payload(args: Args, client: SigningClient) {
|
||||
};
|
||||
|
||||
let address = account_id_to_cw_addr(&client.address());
|
||||
let proxy = if args.with_vesting_account {
|
||||
Some(account_id_to_cw_addr(
|
||||
client.vesting_contract_address().unwrap(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let payload = construct_gateway_bonding_sign_payload(nonce, address, coin, gateway);
|
||||
let payload = construct_gateway_bonding_sign_payload(nonce, address, proxy, coin, gateway);
|
||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
||||
println!("{}", args.output.format(&wrapper))
|
||||
}
|
||||
|
||||
@@ -5,21 +5,33 @@ use crate::context::SigningClient;
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
/// Label that is going to be used for creating the family
|
||||
#[arg(long)]
|
||||
pub family_label: String,
|
||||
|
||||
/// Indicates whether the family is going to get created via a vesting account
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
}
|
||||
|
||||
pub async fn create_family(args: Args, client: SigningClient) {
|
||||
info!("Create family");
|
||||
|
||||
let res = client
|
||||
.create_family(args.family_label, None)
|
||||
.await
|
||||
.expect("failed to create family");
|
||||
let res = if args.with_vesting_account {
|
||||
client
|
||||
.vesting_create_family(args.family_label, None)
|
||||
.await
|
||||
.expect("failed to create family with vesting account")
|
||||
} else {
|
||||
client
|
||||
.create_family(args.family_label, None)
|
||||
.await
|
||||
.expect("failed to create family")
|
||||
};
|
||||
|
||||
info!("Family creation result: {:?}", res);
|
||||
}
|
||||
|
||||
+16
-3
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::QueryClient;
|
||||
use crate::utils::DataWrapper;
|
||||
use crate::utils::{account_id_to_cw_addr, DataWrapper};
|
||||
use clap::Parser;
|
||||
use cosmrs::AccountId;
|
||||
use log::info;
|
||||
@@ -10,7 +10,7 @@ use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_mixnet_contract_common::construct_family_join_permit;
|
||||
use nym_mixnet_contract_common::families::FamilyHead;
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
@@ -18,6 +18,10 @@ pub struct Args {
|
||||
#[arg(long)]
|
||||
pub address: AccountId,
|
||||
|
||||
/// Indicates whether the member joining the family is going to use the vesting account for joining.
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
|
||||
// might as well validate the value when parsing the arguments
|
||||
/// Identity of the member for whom we're issuing the permit
|
||||
#[arg(long)]
|
||||
@@ -64,9 +68,18 @@ pub async fn create_family_join_permit_sign_payload(args: Args, client: QueryCli
|
||||
}
|
||||
};
|
||||
|
||||
// let address = account_id_to_cw_addr(&args.address);
|
||||
let proxy = if args.with_vesting_account {
|
||||
Some(account_id_to_cw_addr(
|
||||
client.vesting_contract_address().unwrap(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let head = FamilyHead::new(mixnode.bond_information.identity());
|
||||
|
||||
let payload = construct_family_join_permit(nonce, head, args.member.to_base58_string());
|
||||
let payload = construct_family_join_permit(nonce, head, proxy, args.member.to_base58_string());
|
||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
||||
println!("{}", args.output.format(&wrapper))
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_mixnet_contract_common::families::FamilyHead;
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
@@ -15,6 +16,10 @@ pub struct Args {
|
||||
#[arg(long)]
|
||||
pub family_head: identity::PublicKey,
|
||||
|
||||
/// Indicates whether the member joining the family is going to do so via the vesting contract
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
|
||||
/// Permission, as provided by the family head, for joining the family
|
||||
#[arg(long)]
|
||||
pub join_permit: MessageSignature,
|
||||
@@ -25,10 +30,17 @@ pub async fn join_family(args: Args, client: SigningClient) {
|
||||
|
||||
let family_head = FamilyHead::new(args.family_head.to_base58_string());
|
||||
|
||||
let res = client
|
||||
.join_family(args.join_permit, family_head, None)
|
||||
.await
|
||||
.expect("failed to join family");
|
||||
let res = if args.with_vesting_account {
|
||||
client
|
||||
.vesting_join_family(args.join_permit, family_head, None)
|
||||
.await
|
||||
.expect("failed to join family with vesting account")
|
||||
} else {
|
||||
client
|
||||
.join_family(args.join_permit, family_head, None)
|
||||
.await
|
||||
.expect("failed to join family")
|
||||
};
|
||||
|
||||
info!("Family join result: {:?}", res);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,17 @@ use log::info;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_mixnet_contract_common::families::FamilyHead;
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
/// The head of the family that we intend to leave
|
||||
#[arg(long)]
|
||||
pub family_head: identity::PublicKey,
|
||||
|
||||
/// Indicates whether we joined the family via the vesting contract
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
}
|
||||
|
||||
pub async fn leave_family(args: Args, client: SigningClient) {
|
||||
@@ -20,10 +25,17 @@ pub async fn leave_family(args: Args, client: SigningClient) {
|
||||
|
||||
let family_head = FamilyHead::new(args.family_head.to_base58_string());
|
||||
|
||||
let res = client
|
||||
.leave_family(family_head, None)
|
||||
.await
|
||||
.expect("failed to leave family");
|
||||
let res = if args.with_vesting_account {
|
||||
client
|
||||
.vesting_leave_family(family_head, None)
|
||||
.await
|
||||
.expect("failed to leave family with vesting account")
|
||||
} else {
|
||||
client
|
||||
.leave_family(family_head, None)
|
||||
.await
|
||||
.expect("failed to leave family")
|
||||
};
|
||||
|
||||
info!("Family leave result: {:?}", res);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::context::SigningClient;
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {}
|
||||
|
||||
pub async fn migrate_vested_mixnode(_args: Args, client: SigningClient) {
|
||||
let res = client
|
||||
.migrate_vested_mixnode(None)
|
||||
.await
|
||||
.expect("failed to migrate mixnode!");
|
||||
|
||||
info!("migration result: {:?}", res)
|
||||
}
|
||||
+13
-2
@@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode
|
||||
use nym_network_defaults::{
|
||||
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
||||
};
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
|
||||
use nym_validator_client::nyxd::CosmWasmCoin;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -52,6 +52,10 @@ pub struct Args {
|
||||
)]
|
||||
pub amount: u128,
|
||||
|
||||
/// Indicates whether the mixnode is going to get bonded via a vesting account
|
||||
#[arg(long)]
|
||||
pub with_vesting_account: bool,
|
||||
|
||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||
output: OutputFormat,
|
||||
}
|
||||
@@ -96,9 +100,16 @@ pub async fn create_payload(args: Args, client: SigningClient) {
|
||||
};
|
||||
|
||||
let address = account_id_to_cw_addr(&client.address());
|
||||
let proxy = if args.with_vesting_account {
|
||||
Some(account_id_to_cw_addr(
|
||||
client.vesting_contract_address().unwrap(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let payload =
|
||||
construct_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
|
||||
construct_mixnode_bonding_sign_payload(nonce, address, proxy, coin, mixnode, cost_params);
|
||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
||||
println!("{}", args.output.format(&wrapper))
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ pub mod bond_mixnode;
|
||||
pub mod decrease_pledge;
|
||||
pub mod families;
|
||||
pub mod keys;
|
||||
pub mod migrate_vested_mixnode;
|
||||
pub mod mixnode_bonding_sign_payload;
|
||||
pub mod pledge_more;
|
||||
pub mod rewards;
|
||||
@@ -53,6 +52,4 @@ pub enum MixnetOperatorsMixnodeCommands {
|
||||
DecreasePledge(decrease_pledge::Args),
|
||||
/// Decrease pledge with locked tokens
|
||||
DecreasePledgeVesting(vesting_decrease_pledge::Args),
|
||||
/// Migrate the mixnode to use liquid tokens
|
||||
MigrateVestedNode(migrate_vested_mixnode::Args),
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ where
|
||||
#[derive(Serialize)]
|
||||
pub struct ContractMessageContent<T> {
|
||||
pub sender: Addr,
|
||||
pub proxy: Option<Addr>,
|
||||
pub funds: Vec<Coin>,
|
||||
pub data: T,
|
||||
}
|
||||
@@ -232,17 +233,25 @@ where
|
||||
}
|
||||
|
||||
impl<T> ContractMessageContent<T> {
|
||||
pub fn new(sender: Addr, funds: Vec<Coin>, data: T) -> Self {
|
||||
pub fn new(sender: Addr, proxy: Option<Addr>, funds: Vec<Coin>, data: T) -> Self {
|
||||
ContractMessageContent {
|
||||
sender,
|
||||
proxy,
|
||||
funds,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_info(info: MessageInfo, signer: Addr, data: T) -> Self {
|
||||
let proxy = if info.sender == signer {
|
||||
None
|
||||
} else {
|
||||
Some(info.sender)
|
||||
};
|
||||
|
||||
ContractMessageContent {
|
||||
sender: signer,
|
||||
proxy,
|
||||
funds: info.funds,
|
||||
data,
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@ use cosmwasm_std::Coin;
|
||||
#[cw_serde]
|
||||
pub struct PoolCounters {
|
||||
pub total_deposited: Coin,
|
||||
pub total_redeemed: Coin,
|
||||
pub total_redeemed_gateways: Coin,
|
||||
pub total_redeemed_holding: Coin,
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ impl Delegation {
|
||||
cumulative_reward_ratio: Decimal,
|
||||
amount: Coin,
|
||||
height: u64,
|
||||
proxy: Option<Addr>,
|
||||
) -> Self {
|
||||
assert!(
|
||||
amount.amount <= TOKEN_SUPPLY,
|
||||
@@ -77,7 +78,7 @@ impl Delegation {
|
||||
cumulative_reward_ratio,
|
||||
amount,
|
||||
height,
|
||||
proxy: None,
|
||||
proxy,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{EpochEventId, EpochState, IdentityKey, MixId, OperatingCostRange, ProfitMarginRange};
|
||||
use crate::{EpochEventId, EpochState, IdentityKey, MixId};
|
||||
use contracts_common::signing::verifier::ApiVerifierError;
|
||||
use contracts_common::Percent;
|
||||
use cosmwasm_std::{Addr, Coin, Decimal, Uint128};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -77,11 +76,21 @@ pub enum MixnetContractError {
|
||||
#[error("Received multiple coin types during staking")]
|
||||
MultipleDenoms,
|
||||
|
||||
#[error("Proxy address mismatch, expected {existing}, got {incoming}")]
|
||||
ProxyMismatch { existing: String, incoming: String },
|
||||
|
||||
#[error("Proxy address ({received}) is not set to the vesting contract ({vesting_contract})")]
|
||||
ProxyIsNotVestingContract {
|
||||
received: Addr,
|
||||
vesting_contract: Addr,
|
||||
},
|
||||
#[error(
|
||||
"Sender of this message ({received}) is not the vesting contract ({vesting_contract})"
|
||||
)]
|
||||
SenderIsNotVestingContract {
|
||||
received: Addr,
|
||||
vesting_contract: Addr,
|
||||
},
|
||||
|
||||
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
|
||||
MalformedEd25519IdentityKey(String),
|
||||
@@ -230,30 +239,6 @@ pub enum MixnetContractError {
|
||||
#[from]
|
||||
source: ApiVerifierError,
|
||||
},
|
||||
|
||||
#[error("this operation is no longer allowed to be performed with vesting tokens. please move them to your liquid balance and try again")]
|
||||
DisabledVestingOperation,
|
||||
|
||||
#[error(
|
||||
"this mixnode has not been bonded with the vesting tokens or has already been migrated"
|
||||
)]
|
||||
NotAVestingMixnode,
|
||||
|
||||
#[error("this delegation has not been performed with the vesting tokens or has already been migrated")]
|
||||
NotAVestingDelegation,
|
||||
|
||||
#[error("the provided profit margin ({provided}) is outside the allowed range: {range}")]
|
||||
ProfitMarginOutsideRange {
|
||||
provided: Percent,
|
||||
range: ProfitMarginRange,
|
||||
},
|
||||
|
||||
#[error("the provided interval operating cost ({provided}{denom}) is outside the allowed range: {range}")]
|
||||
OperatingCostOutsideRange {
|
||||
denom: String,
|
||||
provided: Uint128,
|
||||
range: OperatingCostRange,
|
||||
},
|
||||
}
|
||||
|
||||
impl MixnetContractError {
|
||||
|
||||
@@ -103,6 +103,7 @@ impl Display for MixnetEventType {
|
||||
// attributes that are used in multiple places
|
||||
pub const OWNER_KEY: &str = "owner";
|
||||
pub const AMOUNT_KEY: &str = "amount";
|
||||
pub const PROXY_KEY: &str = "proxy";
|
||||
|
||||
// event-specific attributes
|
||||
|
||||
@@ -162,6 +163,7 @@ pub const NEW_EPOCHS_IN_INTERVAL: &str = "new_epochs_in_interval";
|
||||
pub fn new_delegation_event(
|
||||
created_at: BlockHeight,
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: &Coin,
|
||||
mix_id: MixId,
|
||||
unit_reward: Decimal,
|
||||
@@ -169,34 +171,58 @@ pub fn new_delegation_event(
|
||||
Event::new(MixnetEventType::Delegation)
|
||||
.add_attribute(EVENT_CREATION_HEIGHT_KEY, created_at.to_string())
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
|
||||
.add_attribute(UNIT_REWARD_KEY, unit_reward.to_string())
|
||||
}
|
||||
|
||||
pub fn new_delegation_on_unbonded_node_event(delegator: &Addr, mix_id: MixId) -> Event {
|
||||
pub fn new_delegation_on_unbonded_node_event(
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::Delegation)
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
|
||||
}
|
||||
|
||||
pub fn new_pending_delegation_event(delegator: &Addr, amount: &Coin, mix_id: MixId) -> Event {
|
||||
pub fn new_pending_delegation_event(
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: &Coin,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::PendingDelegation)
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
|
||||
}
|
||||
|
||||
pub fn new_withdraw_operator_reward_event(owner: &Addr, amount: Coin, mix_id: MixId) -> Event {
|
||||
pub fn new_withdraw_operator_reward_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: Coin,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::WithdrawOperatorReward)
|
||||
.add_attribute(OWNER_KEY, owner.as_str())
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
}
|
||||
|
||||
pub fn new_withdraw_delegator_reward_event(delegator: &Addr, amount: Coin, mix_id: MixId) -> Event {
|
||||
pub fn new_withdraw_delegator_reward_event(
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: Coin,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::WithdrawDelegatorReward)
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
|
||||
}
|
||||
@@ -252,43 +278,59 @@ pub fn new_pending_rewarding_params_update_event(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_undelegation_event(created_at: BlockHeight, delegator: &Addr, mix_id: MixId) -> Event {
|
||||
pub fn new_undelegation_event(
|
||||
created_at: BlockHeight,
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::Undelegation)
|
||||
.add_attribute(EVENT_CREATION_HEIGHT_KEY, created_at.to_string())
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
}
|
||||
|
||||
pub fn new_pending_undelegation_event(delegator: &Addr, mix_id: MixId) -> Event {
|
||||
pub fn new_pending_undelegation_event(
|
||||
delegator: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::PendingUndelegation)
|
||||
.add_attribute(DELEGATOR_KEY, delegator)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
}
|
||||
|
||||
pub fn new_gateway_bonding_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: &Coin,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::GatewayBonding)
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_attribute(NODE_IDENTITY_KEY, identity)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
}
|
||||
|
||||
pub fn new_gateway_unbonding_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: &Coin,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::GatewayUnbonding)
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_attribute(NODE_IDENTITY_KEY, identity)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
}
|
||||
|
||||
pub fn new_mixnode_bonding_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
amount: &Coin,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
mix_id: MixId,
|
||||
@@ -299,6 +341,7 @@ pub fn new_mixnode_bonding_event(
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
.add_attribute(NODE_IDENTITY_KEY, identity)
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(ASSIGNED_LAYER_KEY, assigned_layer)
|
||||
.add_attribute(AMOUNT_KEY, amount.to_string())
|
||||
}
|
||||
@@ -337,6 +380,7 @@ pub fn new_mixnode_unbonding_event(created_at: BlockHeight, mix_id: MixId) -> Ev
|
||||
|
||||
pub fn new_pending_mixnode_unbonding_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
identity: IdentityKeyRef<'_>,
|
||||
mix_id: MixId,
|
||||
) -> Event {
|
||||
@@ -344,33 +388,43 @@ pub fn new_pending_mixnode_unbonding_event(
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
.add_attribute(NODE_IDENTITY_KEY, identity)
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
}
|
||||
|
||||
pub fn new_mixnode_config_update_event(
|
||||
mix_id: MixId,
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
update: &MixNodeConfigUpdate,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::MixnodeConfigUpdate)
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(UPDATED_MIXNODE_CONFIG_KEY, update.to_inline_json())
|
||||
}
|
||||
|
||||
pub fn new_gateway_config_update_event(owner: &Addr, update: &GatewayConfigUpdate) -> Event {
|
||||
pub fn new_gateway_config_update_event(
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
update: &GatewayConfigUpdate,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::GatewayConfigUpdate)
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(UPDATED_GATEWAY_CONFIG_KEY, update.to_inline_json())
|
||||
}
|
||||
|
||||
pub fn new_mixnode_pending_cost_params_update_event(
|
||||
mix_id: MixId,
|
||||
owner: &Addr,
|
||||
proxy: &Option<Addr>,
|
||||
new_costs: &MixNodeCostParams,
|
||||
) -> Event {
|
||||
Event::new(MixnetEventType::PendingMixnodeCostParamsUpdate)
|
||||
.add_attribute(MIX_ID_KEY, mix_id.to_string())
|
||||
.add_attribute(OWNER_KEY, owner)
|
||||
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
|
||||
.add_attribute(UPDATED_MIXNODE_COST_PARAMS_KEY, new_costs.to_inline_json())
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::{IdentityKey, IdentityKeyRef};
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::Addr;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::fmt::{Display, Formatter};
|
||||
@@ -83,10 +84,10 @@ impl FamilyHead {
|
||||
}
|
||||
|
||||
impl Family {
|
||||
pub fn new(head: FamilyHead, label: String) -> Self {
|
||||
pub fn new(head: FamilyHead, proxy: Option<Addr>, label: String) -> Self {
|
||||
Family {
|
||||
head,
|
||||
proxy: None,
|
||||
proxy: proxy.map(|p| p.to_string()),
|
||||
label,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,13 +55,19 @@ pub struct GatewayBond {
|
||||
}
|
||||
|
||||
impl GatewayBond {
|
||||
pub fn new(pledge_amount: Coin, owner: Addr, block_height: u64, gateway: Gateway) -> Self {
|
||||
pub fn new(
|
||||
pledge_amount: Coin,
|
||||
owner: Addr,
|
||||
block_height: u64,
|
||||
gateway: Gateway,
|
||||
proxy: Option<Addr>,
|
||||
) -> Self {
|
||||
GatewayBond {
|
||||
pledge_amount,
|
||||
owner,
|
||||
block_height,
|
||||
gateway,
|
||||
proxy: None,
|
||||
proxy,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@ use crate::helpers::IntoBaseDecimal;
|
||||
use crate::reward_params::{NodeRewardParams, RewardingParams};
|
||||
use crate::rewarding::helpers::truncate_reward;
|
||||
use crate::rewarding::RewardDistribution;
|
||||
use crate::{
|
||||
Delegation, EpochEventId, EpochId, IdentityKey, MixId, OperatingCostRange, Percent,
|
||||
ProfitMarginRange, SphinxKey,
|
||||
};
|
||||
use crate::{Delegation, EpochEventId, EpochId, IdentityKey, MixId, Percent, SphinxKey};
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::{Addr, Coin, Decimal, StdResult, Uint128};
|
||||
use schemars::JsonSchema;
|
||||
@@ -155,16 +152,6 @@ impl MixNodeRewarding {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalise_profit_margin(&mut self, allowed_range: ProfitMarginRange) {
|
||||
self.cost_params.profit_margin_percent =
|
||||
allowed_range.normalise(self.cost_params.profit_margin_percent)
|
||||
}
|
||||
|
||||
pub fn normalise_operating_cost(&mut self, allowed_range: OperatingCostRange) {
|
||||
self.cost_params.interval_operating_cost.amount =
|
||||
allowed_range.normalise(self.cost_params.interval_operating_cost.amount)
|
||||
}
|
||||
|
||||
/// Determines whether this node is still bonded. This is performed via a simple check,
|
||||
/// if there are no tokens left associated with the operator, it means they have unbonded
|
||||
/// and those params only exist for the purposes of calculating rewards for delegators that
|
||||
@@ -531,6 +518,7 @@ impl MixNodeBond {
|
||||
original_pledge: Coin,
|
||||
layer: Layer,
|
||||
mix_node: MixNode,
|
||||
proxy: Option<Addr>,
|
||||
bonding_height: u64,
|
||||
) -> Self {
|
||||
MixNodeBond {
|
||||
@@ -539,7 +527,7 @@ impl MixNodeBond {
|
||||
original_pledge,
|
||||
layer,
|
||||
mix_node,
|
||||
proxy: None,
|
||||
proxy,
|
||||
bonding_height,
|
||||
is_unbonding: false,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::delegation::{self, OwnerProxySubKey};
|
||||
@@ -12,7 +12,6 @@ use crate::reward_params::{
|
||||
IntervalRewardParams, IntervalRewardingParamsUpdate, Performance, RewardingParams,
|
||||
};
|
||||
use crate::types::{ContractStateParams, LayerAssignment, MixId};
|
||||
use crate::{OperatingCostRange, ProfitMarginRange};
|
||||
use contracts_common::{signing::MessageSignature, IdentityKey, Percent};
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::{Coin, Decimal};
|
||||
@@ -58,12 +57,6 @@ pub struct InstantiateMsg {
|
||||
pub epochs_in_interval: u32,
|
||||
pub epoch_duration: Duration,
|
||||
pub initial_rewarding_params: InitialRewardingParams,
|
||||
|
||||
#[serde(default)]
|
||||
pub profit_margin: ProfitMarginRange,
|
||||
|
||||
#[serde(default)]
|
||||
pub interval_operating_cost: OperatingCostRange,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
@@ -276,12 +269,6 @@ pub enum ExecuteMsg {
|
||||
owner: String,
|
||||
},
|
||||
|
||||
// vesting migration:
|
||||
MigrateVestedMixNode {},
|
||||
MigrateVestedDelegation {
|
||||
mix_id: MixId,
|
||||
},
|
||||
|
||||
// testing-only
|
||||
#[cfg(feature = "contract-testing")]
|
||||
TestingResolveAllPendingEvents {
|
||||
@@ -394,9 +381,6 @@ impl ExecuteMsg {
|
||||
ExecuteMsg::WithdrawDelegatorRewardOnBehalf { mix_id, .. } => {
|
||||
format!("withdrawing delegator reward from mixnode {mix_id} on behalf")
|
||||
}
|
||||
ExecuteMsg::MigrateVestedMixNode { .. } => "migrate vested mixnode".into(),
|
||||
ExecuteMsg::MigrateVestedDelegation { .. } => "migrate vested delegation".to_string(),
|
||||
|
||||
#[cfg(feature = "contract-testing")]
|
||||
ExecuteMsg::TestingResolveAllPendingEvents { .. } => {
|
||||
"resolving all pending events".into()
|
||||
|
||||
@@ -38,7 +38,6 @@ pub enum PendingEpochEventKind {
|
||||
/// Request to create a delegation towards particular mixnode.
|
||||
/// Note that if such delegation already exists, it will get updated with the provided token amount.
|
||||
#[serde(alias = "Delegate")]
|
||||
#[non_exhaustive]
|
||||
Delegate {
|
||||
/// The address of the owner of the delegation.
|
||||
owner: Addr,
|
||||
@@ -56,7 +55,6 @@ pub enum PendingEpochEventKind {
|
||||
|
||||
/// Request to remove delegation from particular mixnode.
|
||||
#[serde(alias = "Undelegate")]
|
||||
#[non_exhaustive]
|
||||
Undelegate {
|
||||
/// The address of the owner of the delegation.
|
||||
owner: Addr,
|
||||
@@ -111,23 +109,6 @@ impl PendingEpochEventKind {
|
||||
kind: self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_delegate(owner: Addr, mix_id: MixId, amount: Coin) -> Self {
|
||||
PendingEpochEventKind::Delegate {
|
||||
owner,
|
||||
mix_id,
|
||||
amount,
|
||||
proxy: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_undelegate(owner: Addr, mix_id: MixId) -> Self {
|
||||
PendingEpochEventKind::Undelegate {
|
||||
owner,
|
||||
mix_id,
|
||||
proxy: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent {
|
||||
|
||||
+1
@@ -47,6 +47,7 @@ impl SimulatedNode {
|
||||
self.rewarding_details.total_unit_reward,
|
||||
delegation,
|
||||
42,
|
||||
None,
|
||||
);
|
||||
|
||||
self.delegations.insert(delegator, delegation);
|
||||
|
||||
@@ -37,12 +37,13 @@ impl SigningPurpose for MixnodeBondingPayload {
|
||||
pub fn construct_mixnode_bonding_sign_payload(
|
||||
nonce: Nonce,
|
||||
sender: Addr,
|
||||
proxy: Option<Addr>,
|
||||
pledge: Coin,
|
||||
mix_node: MixNode,
|
||||
cost_params: MixNodeCostParams,
|
||||
) -> SignableMixNodeBondingMsg {
|
||||
let payload = MixnodeBondingPayload::new(mix_node, cost_params);
|
||||
let content = ContractMessageContent::new(sender, vec![pledge], payload);
|
||||
let content = ContractMessageContent::new(sender, proxy, vec![pledge], payload);
|
||||
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
@@ -67,11 +68,12 @@ impl SigningPurpose for GatewayBondingPayload {
|
||||
pub fn construct_gateway_bonding_sign_payload(
|
||||
nonce: Nonce,
|
||||
sender: Addr,
|
||||
proxy: Option<Addr>,
|
||||
pledge: Coin,
|
||||
gateway: Gateway,
|
||||
) -> SignableGatewayBondingMsg {
|
||||
let payload = GatewayBondingPayload::new(gateway);
|
||||
let content = ContractMessageContent::new(sender, vec![pledge], payload);
|
||||
let content = ContractMessageContent::new(sender, proxy, vec![pledge], payload);
|
||||
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
@@ -80,14 +82,17 @@ pub fn construct_gateway_bonding_sign_payload(
|
||||
pub struct FamilyJoinPermit {
|
||||
// the granter of this permit
|
||||
family_head: FamilyHead,
|
||||
// whether the **member** will want to join via the proxy (i.e. vesting contract)
|
||||
proxy: Option<Addr>,
|
||||
// the actual member we want to permit to join
|
||||
member_node: IdentityKey,
|
||||
}
|
||||
|
||||
impl FamilyJoinPermit {
|
||||
pub fn new(family_head: FamilyHead, member_node: IdentityKey) -> Self {
|
||||
pub fn new(family_head: FamilyHead, proxy: Option<Addr>, member_node: IdentityKey) -> Self {
|
||||
Self {
|
||||
family_head,
|
||||
proxy,
|
||||
member_node,
|
||||
}
|
||||
}
|
||||
@@ -102,9 +107,10 @@ impl SigningPurpose for FamilyJoinPermit {
|
||||
pub fn construct_family_join_permit(
|
||||
nonce: Nonce,
|
||||
family_head: FamilyHead,
|
||||
proxy: Option<Addr>,
|
||||
member_node: IdentityKey,
|
||||
) -> SignableFamilyJoinPermitMsg {
|
||||
let payload = FamilyJoinPermit::new(family_head, member_node);
|
||||
let payload = FamilyJoinPermit::new(family_head, proxy, member_node);
|
||||
|
||||
// note: we're NOT wrapping it in `ContractMessageContent` because the family head is not going to be the one
|
||||
// sending the message to the contract
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
|
||||
use crate::error::MixnetContractError;
|
||||
use crate::Layer;
|
||||
use contracts_common::Percent;
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::Addr;
|
||||
use cosmwasm_std::Coin;
|
||||
use cosmwasm_std::{Addr, Uint128};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::Index;
|
||||
|
||||
// type aliases for better reasoning about available data
|
||||
@@ -17,65 +15,6 @@ pub type SphinxKeyRef<'a> = &'a str;
|
||||
pub type MixId = u32;
|
||||
pub type BlockHeight = u64;
|
||||
|
||||
#[cw_serde]
|
||||
pub struct RangedValue<T> {
|
||||
pub minimum: T,
|
||||
pub maximum: T,
|
||||
}
|
||||
|
||||
impl<T> Copy for RangedValue<T> where T: Copy {}
|
||||
|
||||
pub type ProfitMarginRange = RangedValue<Percent>;
|
||||
pub type OperatingCostRange = RangedValue<Uint128>;
|
||||
|
||||
impl<T> Display for RangedValue<T>
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} - {}", self.minimum, self.maximum)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ProfitMarginRange {
|
||||
fn default() -> Self {
|
||||
ProfitMarginRange {
|
||||
minimum: Percent::zero(),
|
||||
maximum: Percent::hundred(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OperatingCostRange {
|
||||
fn default() -> Self {
|
||||
OperatingCostRange {
|
||||
minimum: Uint128::zero(),
|
||||
|
||||
// 1 billion (native tokens, i.e. 1 billion * 1'000'000 base tokens) - the total supply
|
||||
maximum: Uint128::new(1_000_000_000_000_000),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RangedValue<T>
|
||||
where
|
||||
T: Copy + PartialOrd + PartialEq,
|
||||
{
|
||||
pub fn normalise(&self, value: T) -> T {
|
||||
if value < self.minimum {
|
||||
self.minimum
|
||||
} else if value > self.maximum {
|
||||
self.maximum
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
pub fn within_range(&self, value: T) -> bool {
|
||||
value >= self.minimum && value <= self.maximum
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies layer assignment for the given mixnode.
|
||||
#[cw_serde]
|
||||
pub struct LayerAssignment {
|
||||
@@ -215,14 +154,4 @@ pub struct ContractStateParams {
|
||||
|
||||
/// Minimum amount a gateway must pledge to get into the system.
|
||||
pub minimum_gateway_pledge: Coin,
|
||||
|
||||
/// Defines the allowed profit margin range of operators.
|
||||
/// default: 0% - 100%
|
||||
#[serde(default)]
|
||||
pub profit_margin: ProfitMarginRange,
|
||||
|
||||
/// Defines the allowed interval operating cost range of operators.
|
||||
/// default: 0 - 1'000'000'000'000'000 (1 Billion native tokens - the total supply)
|
||||
#[serde(default)]
|
||||
pub interval_operating_cost: OperatingCostRange,
|
||||
}
|
||||
|
||||
@@ -167,11 +167,3 @@ pub fn new_track_undelegation_event() -> Event {
|
||||
pub fn new_track_reward_event() -> Event {
|
||||
Event::new(TRACK_REWARD_EVENT_TYPE)
|
||||
}
|
||||
|
||||
pub fn new_track_migrate_mixnode_event() -> Event {
|
||||
Event::new("track_migrate_vesting_mixnode")
|
||||
}
|
||||
|
||||
pub fn new_track_migrate_delegation_event() -> Event {
|
||||
Event::new("track_migrate_vesting_delegation")
|
||||
}
|
||||
|
||||
@@ -136,14 +136,6 @@ pub enum ExecuteMsg {
|
||||
address: String,
|
||||
cap: PledgeCap,
|
||||
},
|
||||
TrackMigratedMixnode {
|
||||
owner: String,
|
||||
},
|
||||
// no need to track migrated gateways as there are no vesting gateways on mainnet
|
||||
TrackMigratedDelegation {
|
||||
owner: String,
|
||||
mix_id: MixId,
|
||||
},
|
||||
}
|
||||
|
||||
impl ExecuteMsg {
|
||||
@@ -179,10 +171,6 @@ impl ExecuteMsg {
|
||||
ExecuteMsg::TransferOwnership { .. } => "VestingExecuteMsg::TransferOwnership",
|
||||
ExecuteMsg::UpdateStakingAddress { .. } => "VestingExecuteMsg::UpdateStakingAddress",
|
||||
ExecuteMsg::UpdateLockedPledgeCap { .. } => "VestingExecuteMsg::UpdateLockedPledgeCap",
|
||||
ExecuteMsg::TrackMigratedMixnode { .. } => "VestingExecuteMsg::TrackMigratedMixnode",
|
||||
ExecuteMsg::TrackMigratedDelegation { .. } => {
|
||||
"VestingExecuteMsg::TrackMigratedDelegation"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,6 @@ CREATE TABLE ecash_ticketbook
|
||||
-- introduce a way for us to introduce breaking changes in serialization of data
|
||||
serialization_revision INTEGER NOT NULL,
|
||||
|
||||
-- the type of the associated ticketbook
|
||||
ticketbook_type TEXT NOT NULL,
|
||||
|
||||
-- the actual crypto data of the ticketbook (wallet, keys, etc.)
|
||||
ticketbook_data BLOB NOT NULL UNIQUE,
|
||||
|
||||
|
||||
@@ -175,7 +175,6 @@ impl MemoryEcachTicketbookManager {
|
||||
.map(|t| BasicTicketbookInformation {
|
||||
id: t.ticketbook_id,
|
||||
expiration_date: t.ticketbook.expiration_date(),
|
||||
ticketbook_type: t.ticketbook.ticketbook_type().to_string(),
|
||||
epoch_id: t.ticketbook.epoch_id() as u32,
|
||||
total_tickets: t.ticketbook.spent_tickets() as u32,
|
||||
used_tickets: t.ticketbook.params_total_tickets() as u32,
|
||||
|
||||
@@ -61,13 +61,11 @@ impl SqliteEcashTicketbookManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn insert_new_ticketbook(
|
||||
&self,
|
||||
serialisation_revision: u8,
|
||||
data: &[u8],
|
||||
expiration_date: Date,
|
||||
typ: &str,
|
||||
epoch_id: u32,
|
||||
total_tickets: u32,
|
||||
used_tickets: u32,
|
||||
@@ -75,13 +73,12 @@ impl SqliteEcashTicketbookManager {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO ecash_ticketbook
|
||||
(serialization_revision, ticketbook_data, expiration_date, ticketbook_type, epoch_id, total_tickets, used_tickets)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
(serialization_revision, ticketbook_data, expiration_date, epoch_id, total_tickets, used_tickets)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
"#,
|
||||
serialisation_revision,
|
||||
data,
|
||||
expiration_date,
|
||||
typ,
|
||||
epoch_id,
|
||||
total_tickets,
|
||||
used_tickets,
|
||||
@@ -95,7 +92,7 @@ impl SqliteEcashTicketbookManager {
|
||||
) -> Result<Vec<BasicTicketbookInformation>, sqlx::Error> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
SELECT id, expiration_date, ticketbook_type, epoch_id, total_tickets, used_tickets
|
||||
SELECT id, expiration_date, epoch_id, total_tickets, used_tickets
|
||||
FROM ecash_ticketbook
|
||||
"#,
|
||||
)
|
||||
|
||||
@@ -19,7 +19,6 @@ pub struct RetrievedPendingTicketbook {
|
||||
pub struct BasicTicketbookInformation {
|
||||
pub id: i64,
|
||||
pub expiration_date: Date,
|
||||
pub ticketbook_type: String,
|
||||
pub epoch_id: u32,
|
||||
pub total_tickets: u32,
|
||||
pub used_tickets: u32,
|
||||
@@ -32,8 +31,6 @@ pub struct StoredIssuedTicketbook {
|
||||
|
||||
pub serialization_revision: u8,
|
||||
|
||||
pub ticketbook_type: String,
|
||||
|
||||
pub ticketbook_data: Vec<u8>,
|
||||
|
||||
#[zeroize(skip)]
|
||||
|
||||
@@ -114,7 +114,6 @@ impl Storage for PersistentStorage {
|
||||
serialisation_revision,
|
||||
&data,
|
||||
ticketbook.expiration_date(),
|
||||
&ticketbook.ticketbook_type().to_string(),
|
||||
ticketbook.epoch_id() as u32,
|
||||
ticketbook.params_total_tickets() as u32,
|
||||
ticketbook.spent_tickets() as u32,
|
||||
|
||||
@@ -14,9 +14,9 @@ time.workspace = true
|
||||
|
||||
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-credentials-interface = { path = "../../common/credentials-interface" }
|
||||
nym-credential-storage = { path = "../../common/credential-storage", features = ["persistent-storage"] }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client" }
|
||||
nym-config = { path = "../../common/config" }
|
||||
nym-client-core = { path = "../../common/client-core" }
|
||||
nym-compact-ecash = { path = "../../common/nym_offline_compact_ecash" }
|
||||
nym-ecash-time = { path = "../../common/ecash-time" }
|
||||
@@ -1,6 +1,3 @@
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::errors::{Error, Result};
|
||||
use log::*;
|
||||
use nym_bandwidth_controller::acquire::{
|
||||
@@ -10,7 +7,6 @@ use nym_client_core::config::disk_persistence::CommonClientPaths;
|
||||
use nym_config::DEFAULT_DATA_DIR;
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage;
|
||||
use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_ecash_time::ecash_default_expiration_date;
|
||||
use nym_validator_client::coconut::all_ecash_api_clients;
|
||||
use nym_validator_client::nyxd::contract_traits::{
|
||||
@@ -20,12 +16,7 @@ use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub async fn issue_credential<C, S>(
|
||||
client: &C,
|
||||
storage: &S,
|
||||
client_id: &[u8],
|
||||
typ: TicketType,
|
||||
) -> Result<()>
|
||||
pub async fn issue_credential<C, S>(client: &C, storage: &S, client_id: &[u8]) -> Result<()>
|
||||
where
|
||||
C: DkgQueryClient + EcashSigningClient + EcashQueryClient + Send + Sync,
|
||||
S: Storage,
|
||||
@@ -58,7 +49,6 @@ where
|
||||
client,
|
||||
client_id,
|
||||
Some(ticketbook_expiration),
|
||||
typ,
|
||||
)
|
||||
.await?;
|
||||
info!("Deposit done");
|
||||
@@ -75,7 +65,7 @@ where
|
||||
}).map_err(Error::storage_error)?
|
||||
}
|
||||
|
||||
info!("Succeeded adding a ticketbook of type '{typ}'");
|
||||
info!("Succeeded adding a ticketbook");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@ license.workspace = true
|
||||
bls12_381 = { workspace = true, default-features = false }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
strum = { workspace = true, features = ["derive"] }
|
||||
time = { workspace = true, features = ["serde"] }
|
||||
rand = { workspace = true }
|
||||
|
||||
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
|
||||
nym-ecash-time = { path = "../ecash-time" }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-ecash-time = { path = "../ecash-time" }
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_network_defaults::TicketTypeRepr;
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use time::{Date, OffsetDateTime};
|
||||
|
||||
pub use nym_compact_ecash::{
|
||||
@@ -17,6 +15,7 @@ pub use nym_compact_ecash::{
|
||||
PartialCoinIndexSignature,
|
||||
},
|
||||
scheme::expiration_date_signatures::aggregate_expiration_signatures,
|
||||
scheme::expiration_date_signatures::date_scalar,
|
||||
scheme::expiration_date_signatures::{
|
||||
AnnotatedExpirationDateSignature, ExpirationDateSignature, ExpirationDateSignatureShare,
|
||||
PartialExpirationDateSignature,
|
||||
@@ -25,10 +24,10 @@ pub use nym_compact_ecash::{
|
||||
scheme::withdrawal::RequestInfo,
|
||||
scheme::Payment,
|
||||
scheme::{Wallet, WalletSignatures},
|
||||
withdrawal_request, Base58, BlindedSignature, Bytable, EncodedDate, EncodedTicketType,
|
||||
PartialWallet, PayInfo, PublicKeyUser, SecretKeyUser, VerificationKeyAuth, WithdrawalRequest,
|
||||
withdrawal_request, Base58, BlindedSignature, Bytable, PartialWallet, PayInfo, PublicKeyUser,
|
||||
SecretKeyUser, VerificationKeyAuth, WithdrawalRequest,
|
||||
};
|
||||
use nym_ecash_time::{ecash_today, EcashTime};
|
||||
use nym_ecash_time::EcashTime;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CredentialSigningData {
|
||||
@@ -39,8 +38,6 @@ pub struct CredentialSigningData {
|
||||
pub ecash_pub_key: PublicKeyUser,
|
||||
|
||||
pub expiration_date: Date,
|
||||
|
||||
pub ticketbook_type: TicketType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||
@@ -61,7 +58,7 @@ impl CredentialSpendingData {
|
||||
self.payment.spend_verify(
|
||||
verification_key,
|
||||
&self.pay_info,
|
||||
self.spend_date.ecash_unix_timestamp(),
|
||||
date_scalar(self.spend_date.ecash_unix_timestamp()),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -219,112 +216,3 @@ impl From<PayInfo> for NymPayInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Default,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum TicketType {
|
||||
#[default]
|
||||
V1MixnetEntry,
|
||||
V1MixnetExit,
|
||||
V1WireguardEntry,
|
||||
V1WireguardExit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Error)]
|
||||
#[error("provided unknown ticketbook type")]
|
||||
pub struct UnknownTicketType;
|
||||
|
||||
impl TicketType {
|
||||
pub fn to_repr(&self) -> TicketTypeRepr {
|
||||
(*self).into()
|
||||
}
|
||||
|
||||
pub fn encode(&self) -> EncodedTicketType {
|
||||
self.to_repr() as EncodedTicketType
|
||||
}
|
||||
|
||||
pub fn try_from_encoded(val: EncodedTicketType) -> Result<Self, UnknownTicketType> {
|
||||
match val {
|
||||
n if n == TicketTypeRepr::V1MixnetEntry as u8 => {
|
||||
Ok(TicketTypeRepr::V1MixnetEntry.into())
|
||||
}
|
||||
n if n == TicketTypeRepr::V1MixnetExit as u8 => Ok(TicketTypeRepr::V1MixnetExit.into()),
|
||||
n if n == TicketTypeRepr::V1WireguardEntry as u8 => {
|
||||
Ok(TicketTypeRepr::V1WireguardEntry.into())
|
||||
}
|
||||
n if n == TicketTypeRepr::V1WireguardExit as u8 => {
|
||||
Ok(TicketTypeRepr::V1WireguardExit.into())
|
||||
}
|
||||
_ => Err(UnknownTicketType),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TicketType> for TicketTypeRepr {
|
||||
fn from(value: TicketType) -> Self {
|
||||
match value {
|
||||
TicketType::V1MixnetEntry => TicketTypeRepr::V1MixnetEntry,
|
||||
TicketType::V1MixnetExit => TicketTypeRepr::V1MixnetExit,
|
||||
TicketType::V1WireguardEntry => TicketTypeRepr::V1WireguardEntry,
|
||||
TicketType::V1WireguardExit => TicketTypeRepr::V1WireguardExit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TicketTypeRepr> for TicketType {
|
||||
fn from(value: TicketTypeRepr) -> Self {
|
||||
match value {
|
||||
TicketTypeRepr::V1MixnetEntry => TicketType::V1MixnetEntry,
|
||||
TicketTypeRepr::V1MixnetExit => TicketType::V1MixnetExit,
|
||||
TicketTypeRepr::V1WireguardEntry => TicketType::V1WireguardEntry,
|
||||
TicketTypeRepr::V1WireguardExit => TicketType::V1WireguardExit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClientTicket {
|
||||
pub spending_data: CredentialSpendingData,
|
||||
pub ticket_id: i64,
|
||||
}
|
||||
|
||||
impl ClientTicket {
|
||||
pub fn new(spending_data: CredentialSpendingData, ticket_id: i64) -> Self {
|
||||
ClientTicket {
|
||||
spending_data,
|
||||
ticket_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct AvailableBandwidth {
|
||||
pub bytes: i64,
|
||||
pub expiration: OffsetDateTime,
|
||||
}
|
||||
|
||||
impl AvailableBandwidth {
|
||||
pub fn expired(&self) -> bool {
|
||||
self.expiration < ecash_today()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AvailableBandwidth {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bytes: 0,
|
||||
expiration: OffsetDateTime::UNIX_EPOCH,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::ecash::bandwidth::issued::IssuedTicketBook;
|
||||
use crate::ecash::bandwidth::serialiser::VersionedSerialise;
|
||||
use crate::ecash::bandwidth::CredentialSigningData;
|
||||
use crate::ecash::utils::cred_exp_date;
|
||||
use crate::error::Error;
|
||||
use nym_api_requests::ecash::BlindSignRequestBody;
|
||||
use nym_credentials_interface::{
|
||||
aggregate_wallets, generate_keypair_user_from_seed, issue_verify, withdrawal_request,
|
||||
BlindedSignature, KeyPairUser, PartialWallet, TicketType, VerificationKeyAuth,
|
||||
WalletSignatures, WithdrawalRequest,
|
||||
BlindedSignature, KeyPairUser, PartialWallet, VerificationKeyAuth, WalletSignatures,
|
||||
WithdrawalRequest,
|
||||
};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_ecash_contract_common::deposit::DepositId;
|
||||
@@ -19,6 +18,7 @@ use nym_validator_client::nym_api::EpochId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::Date;
|
||||
|
||||
use crate::ecash::bandwidth::serialiser::VersionedSerialise;
|
||||
pub use nym_validator_client::nyxd::{Coin, Hash};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -32,9 +32,6 @@ pub struct IssuanceTicketBook {
|
||||
/// ecash keypair related to the credential
|
||||
ecash_keypair: KeyPairUser,
|
||||
|
||||
/// the type of the ticketbook to be issued
|
||||
ticketbook_type: TicketType,
|
||||
|
||||
/// expiration_date of that credential
|
||||
expiration_date: Date,
|
||||
}
|
||||
@@ -44,14 +41,12 @@ impl IssuanceTicketBook {
|
||||
deposit_id: DepositId,
|
||||
identifier: M,
|
||||
signing_key: identity::PrivateKey,
|
||||
ticketbook_type: TicketType,
|
||||
) -> Self {
|
||||
//this expiration date will get fed to the ecash library, force midnight to be set
|
||||
Self::new_with_expiration(
|
||||
deposit_id,
|
||||
identifier,
|
||||
signing_key,
|
||||
ticketbook_type,
|
||||
ecash_default_expiration_date(),
|
||||
)
|
||||
}
|
||||
@@ -60,7 +55,6 @@ impl IssuanceTicketBook {
|
||||
deposit_id: DepositId,
|
||||
identifier: M,
|
||||
signing_key: identity::PrivateKey,
|
||||
ticketbook_type: TicketType,
|
||||
expiration_date: Date,
|
||||
) -> Self {
|
||||
let ecash_keypair = generate_keypair_user_from_seed(identifier);
|
||||
@@ -68,7 +62,6 @@ impl IssuanceTicketBook {
|
||||
deposit_id,
|
||||
signing_key,
|
||||
ecash_keypair,
|
||||
ticketbook_type,
|
||||
expiration_date,
|
||||
}
|
||||
}
|
||||
@@ -83,10 +76,6 @@ impl IssuanceTicketBook {
|
||||
self.expiration_date
|
||||
}
|
||||
|
||||
pub fn ticketbook_type(&self) -> TicketType {
|
||||
self.ticketbook_type
|
||||
}
|
||||
|
||||
pub fn request_plaintext(request: &WithdrawalRequest, deposit_id: DepositId) -> Vec<u8> {
|
||||
let mut message = request.to_bytes();
|
||||
message.extend_from_slice(&deposit_id.to_be_bytes());
|
||||
@@ -110,7 +99,6 @@ impl IssuanceTicketBook {
|
||||
request_signature,
|
||||
signing_request.ecash_pub_key.clone(),
|
||||
signing_request.expiration_date,
|
||||
signing_request.ticketbook_type,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -145,7 +133,6 @@ impl IssuanceTicketBook {
|
||||
let (withdrawal_request, request_info) = withdrawal_request(
|
||||
self.ecash_keypair.secret_key(),
|
||||
self.expiration_date.ecash_unix_timestamp(),
|
||||
self.ticketbook_type.encode(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -154,7 +141,6 @@ impl IssuanceTicketBook {
|
||||
request_info,
|
||||
ecash_pub_key: self.ecash_keypair.public_key(),
|
||||
expiration_date: self.expiration_date,
|
||||
ticketbook_type: self.ticketbook_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +218,6 @@ impl IssuanceTicketBook {
|
||||
wallet,
|
||||
epoch_id,
|
||||
self.ecash_keypair.secret_key().clone(),
|
||||
self.ticketbook_type,
|
||||
self.expiration_date,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::ecash::bandwidth::CredentialSpendingData;
|
||||
use crate::ecash::utils::ecash_today;
|
||||
use crate::error::Error;
|
||||
use nym_credentials_interface::{
|
||||
CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, TicketType,
|
||||
VerificationKeyAuth, Wallet, WalletSignatures,
|
||||
CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, VerificationKeyAuth,
|
||||
Wallet, WalletSignatures,
|
||||
};
|
||||
use nym_ecash_time::EcashTime;
|
||||
use nym_validator_client::nym_api::EpochId;
|
||||
@@ -36,10 +36,6 @@ pub struct IssuedTicketBook {
|
||||
/// expiration_date for easier discarding
|
||||
#[zeroize(skip)]
|
||||
expiration_date: Date,
|
||||
|
||||
/// the type of the ticketbook to got issued
|
||||
#[zeroize(skip)]
|
||||
ticketbook_type: TicketType,
|
||||
}
|
||||
|
||||
impl IssuedTicketBook {
|
||||
@@ -47,7 +43,6 @@ impl IssuedTicketBook {
|
||||
wallet: WalletSignatures,
|
||||
epoch_id: EpochId,
|
||||
ecash_secret_key: SecretKeyUser,
|
||||
ticketbook_type: TicketType,
|
||||
expiration_date: Date,
|
||||
) -> Self {
|
||||
IssuedTicketBook {
|
||||
@@ -56,7 +51,6 @@ impl IssuedTicketBook {
|
||||
epoch_id,
|
||||
ecash_secret_key,
|
||||
expiration_date,
|
||||
ticketbook_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +58,6 @@ impl IssuedTicketBook {
|
||||
signatures_wallet: WalletSignatures,
|
||||
epoch_id: EpochId,
|
||||
ecash_secret_key: SecretKeyUser,
|
||||
ticketbook_type: TicketType,
|
||||
expiration_date: Date,
|
||||
spent_tickets: u64,
|
||||
) -> Self {
|
||||
@@ -74,7 +67,6 @@ impl IssuedTicketBook {
|
||||
epoch_id,
|
||||
ecash_secret_key,
|
||||
expiration_date,
|
||||
ticketbook_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +78,6 @@ impl IssuedTicketBook {
|
||||
self.epoch_id
|
||||
}
|
||||
|
||||
pub fn ticketbook_type(&self) -> TicketType {
|
||||
self.ticketbook_type
|
||||
}
|
||||
|
||||
pub fn current_serialization_revision(&self) -> u8 {
|
||||
CURRENT_SERIALIZATION_REVISION
|
||||
}
|
||||
|
||||
@@ -36,6 +36,22 @@ pub fn aggregate_verification_keys(
|
||||
)?)
|
||||
}
|
||||
|
||||
pub fn obtain_aggregated_verification_key(
|
||||
_api_clients: &[EcashApiClient],
|
||||
) -> Result<VerificationKeyAuth, Error> {
|
||||
// TODO:
|
||||
// let total = api_clients.len();
|
||||
// let mut rng = thread_rng();
|
||||
// let indices = sample(&mut rng, total, total);
|
||||
// for index in indices {
|
||||
// // randomly try apis until we succeed
|
||||
// // if let Ok(res) = api_clients[index].api_client.get_aggregated_verification_key().await {
|
||||
// // //
|
||||
// // }
|
||||
// }
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn obtain_expiration_date_signatures(
|
||||
ecash_api_clients: &[EcashApiClient],
|
||||
verification_key: &VerificationKeyAuth,
|
||||
@@ -47,7 +63,7 @@ pub async fn obtain_expiration_date_signatures(
|
||||
|
||||
let mut signatures_shares: Vec<_> = Vec::with_capacity(ecash_api_clients.len());
|
||||
|
||||
let expiration_date = cred_exp_date().ecash_unix_timestamp();
|
||||
let expiration_date = cred_exp_date().unix_timestamp() as u64;
|
||||
for ecash_api_client in ecash_api_clients.iter() {
|
||||
match ecash_api_client
|
||||
.api_client
|
||||
|
||||
@@ -6,16 +6,13 @@ use time::{Duration, PrimitiveDateTime, Time};
|
||||
pub use time::{Date, OffsetDateTime};
|
||||
|
||||
pub trait EcashTime {
|
||||
fn ecash_unix_timestamp(&self) -> u32 {
|
||||
fn ecash_unix_timestamp(&self) -> u64 {
|
||||
let ts = self.ecash_datetime().unix_timestamp();
|
||||
|
||||
// just panic on pre-1970 timestamps...
|
||||
assert!(ts > 0);
|
||||
|
||||
// and on anything in 22nd century...
|
||||
assert!(ts <= u32::MAX as i64);
|
||||
|
||||
ts as u32
|
||||
ts as u64
|
||||
}
|
||||
|
||||
fn ecash_date(&self) -> Date {
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
[package]
|
||||
name = "nym-gateway-storage"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
bincode = { workspace = true, optional = true }
|
||||
defguard_wireguard_rs = { workspace = true, optional = true }
|
||||
log = { workspace = true }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
"time",
|
||||
] }
|
||||
time = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
nym-credentials-interface = { path = "../credentials-interface" }
|
||||
nym-gateway-requests = { path = "../gateway-requests" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
|
||||
[build-dependencies]
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
|
||||
[features]
|
||||
wireguard = ["defguard_wireguard_rs", "bincode"]
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
CREATE TABLE wireguard_peer
|
||||
(
|
||||
public_key TEXT NOT NULL PRIMARY KEY UNIQUE,
|
||||
preshared_key TEXT,
|
||||
protocol_version INTEGER,
|
||||
endpoint TEXT,
|
||||
last_handshake TIMESTAMP,
|
||||
tx_bytes BIGINT NOT NULL,
|
||||
rx_bytes BIGINT NOT NULL,
|
||||
persistent_keepalive_interval INTEGER,
|
||||
allowed_ips BLOB NOT NULL,
|
||||
suspended BOOLEAN NOT NULL
|
||||
);
|
||||
@@ -1,182 +0,0 @@
|
||||
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::error::StorageError;
|
||||
use nym_credentials_interface::{AvailableBandwidth, ClientTicket, CredentialSpendingData};
|
||||
use sqlx::FromRow;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub struct PersistedSharedKeys {
|
||||
#[allow(dead_code)]
|
||||
pub id: i64,
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub client_address_bs58: String,
|
||||
pub derived_aes128_ctr_blake3_hmac_keys_bs58: String,
|
||||
}
|
||||
|
||||
pub struct StoredMessage {
|
||||
pub id: i64,
|
||||
#[allow(dead_code)]
|
||||
pub client_address_bs58: String,
|
||||
pub content: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, FromRow)]
|
||||
pub struct PersistedBandwidth {
|
||||
#[allow(dead_code)]
|
||||
pub client_id: i64,
|
||||
pub available: i64,
|
||||
pub expiration: Option<OffsetDateTime>,
|
||||
}
|
||||
|
||||
impl From<PersistedBandwidth> for AvailableBandwidth {
|
||||
fn from(value: PersistedBandwidth) -> Self {
|
||||
AvailableBandwidth {
|
||||
bytes: value.available,
|
||||
expiration: value.expiration.unwrap_or(OffsetDateTime::UNIX_EPOCH),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub struct VerifiedTicket {
|
||||
pub serial_number: Vec<u8>,
|
||||
pub ticket_id: i64,
|
||||
}
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub struct RedemptionProposal {
|
||||
pub proposal_id: i64,
|
||||
pub created_at: OffsetDateTime,
|
||||
}
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub struct UnverifiedTicketData {
|
||||
pub data: Vec<u8>,
|
||||
pub ticket_id: i64,
|
||||
}
|
||||
|
||||
impl TryFrom<UnverifiedTicketData> for ClientTicket {
|
||||
type Error = StorageError;
|
||||
|
||||
fn try_from(value: UnverifiedTicketData) -> Result<Self, Self::Error> {
|
||||
Ok(ClientTicket {
|
||||
spending_data: CredentialSpendingData::try_from_bytes(&value.data).map_err(|_| {
|
||||
StorageError::MalformedStoredTicketData {
|
||||
ticket_id: value.ticket_id,
|
||||
}
|
||||
})?,
|
||||
ticket_id: value.ticket_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
#[derive(Debug, Clone, FromRow)]
|
||||
pub struct WireguardPeer {
|
||||
pub public_key: String,
|
||||
pub preshared_key: Option<String>,
|
||||
pub protocol_version: Option<i64>,
|
||||
pub endpoint: Option<String>,
|
||||
pub last_handshake: Option<sqlx::types::chrono::NaiveDateTime>,
|
||||
pub tx_bytes: i64,
|
||||
pub rx_bytes: i64,
|
||||
pub persistent_keepalive_interval: Option<i64>,
|
||||
pub allowed_ips: Vec<u8>,
|
||||
pub suspended: bool,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
impl From<defguard_wireguard_rs::host::Peer> for WireguardPeer {
|
||||
fn from(value: defguard_wireguard_rs::host::Peer) -> Self {
|
||||
WireguardPeer {
|
||||
public_key: value.public_key.to_string(),
|
||||
preshared_key: value.preshared_key.as_ref().map(|k| k.to_string()),
|
||||
protocol_version: value.protocol_version.map(|v| v as i64),
|
||||
endpoint: value.endpoint.map(|e| e.to_string()),
|
||||
last_handshake: value.last_handshake.and_then(|t| {
|
||||
if let Ok(d) = t.duration_since(std::time::UNIX_EPOCH) {
|
||||
if let Ok(millis) = d.as_millis().try_into() {
|
||||
sqlx::types::chrono::DateTime::from_timestamp_millis(millis)
|
||||
.map(|d| d.naive_utc())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}),
|
||||
tx_bytes: value.tx_bytes as i64,
|
||||
rx_bytes: value.rx_bytes as i64,
|
||||
persistent_keepalive_interval: value.persistent_keepalive_interval.map(|v| v as i64),
|
||||
allowed_ips: bincode::Options::serialize(
|
||||
bincode::DefaultOptions::new(),
|
||||
&value.allowed_ips,
|
||||
)
|
||||
.unwrap_or_default(),
|
||||
suspended: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
impl TryFrom<WireguardPeer> for defguard_wireguard_rs::host::Peer {
|
||||
type Error = crate::error::StorageError;
|
||||
|
||||
fn try_from(value: WireguardPeer) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
public_key: value
|
||||
.public_key
|
||||
.as_str()
|
||||
.try_into()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("public key {e}")))?,
|
||||
preshared_key: value
|
||||
.preshared_key
|
||||
.as_deref()
|
||||
.map(TryFrom::try_from)
|
||||
.transpose()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("preshared key {e}")))?,
|
||||
protocol_version: value
|
||||
.protocol_version
|
||||
.map(TryFrom::try_from)
|
||||
.transpose()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("protocol version {e}")))?,
|
||||
endpoint: value
|
||||
.endpoint
|
||||
.as_deref()
|
||||
.map(|e| e.parse())
|
||||
.transpose()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("endpoint {e}")))?,
|
||||
last_handshake: value.last_handshake.and_then(|t| {
|
||||
let unix_time = std::time::UNIX_EPOCH;
|
||||
if let Ok(millis) = t.and_utc().timestamp_millis().try_into() {
|
||||
let duration = std::time::Duration::from_millis(millis);
|
||||
unix_time.checked_add(duration)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}),
|
||||
tx_bytes: value
|
||||
.tx_bytes
|
||||
.try_into()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("tx bytes {e}")))?,
|
||||
rx_bytes: value
|
||||
.rx_bytes
|
||||
.try_into()
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("rx bytes {e}")))?,
|
||||
persistent_keepalive_interval: value
|
||||
.persistent_keepalive_interval
|
||||
.map(TryFrom::try_from)
|
||||
.transpose()
|
||||
.map_err(|e| {
|
||||
Self::Error::TypeConversion(format!("persistent keepalive interval {e}"))
|
||||
})?,
|
||||
allowed_ips: bincode::Options::deserialize(
|
||||
bincode::DefaultOptions::new(),
|
||||
&value.allowed_ips,
|
||||
)
|
||||
.map_err(|e| Self::Error::TypeConversion(format!("allowed ips {e}")))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::models::WireguardPeer;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct WgPeerManager {
|
||||
connection_pool: sqlx::SqlitePool,
|
||||
}
|
||||
|
||||
impl WgPeerManager {
|
||||
/// Creates new instance of the `WgPeersManager` with the provided sqlite connection pool.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `connection_pool`: database connection pool to use.
|
||||
pub(crate) fn new(connection_pool: sqlx::SqlitePool) -> Self {
|
||||
WgPeerManager { connection_pool }
|
||||
}
|
||||
|
||||
/// Creates a new wireguard peer entry for its particular public key or
|
||||
/// overwrittes the peer entry data if it already existed.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `peer`: peer information needed by wireguard interface.
|
||||
pub(crate) async fn insert_peer(&self, peer: &WireguardPeer) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
"INSERT OR REPLACE INTO wireguard_peer(public_key, preshared_key, protocol_version, endpoint, last_handshake, tx_bytes, rx_bytes, persistent_keepalive_interval, allowed_ips, suspended) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
peer.public_key, peer.preshared_key, peer.protocol_version, peer.endpoint, peer.last_handshake, peer.tx_bytes, peer.rx_bytes, peer.persistent_keepalive_interval, peer.allowed_ips, peer.suspended
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Retrieve the wireguard peer with the provided public key from the storage.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `public_key`: the unique public key of the wireguard peer.
|
||||
pub(crate) async fn retrieve_peer(
|
||||
&self,
|
||||
public_key: &str,
|
||||
) -> Result<Option<WireguardPeer>, sqlx::Error> {
|
||||
sqlx::query_as!(
|
||||
WireguardPeer,
|
||||
r#"
|
||||
SELECT * FROM wireguard_peer
|
||||
WHERE public_key = ?
|
||||
LIMIT 1
|
||||
"#,
|
||||
public_key,
|
||||
)
|
||||
.fetch_optional(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Retrieve all wireguard peers.
|
||||
pub(crate) async fn retrieve_all_peers(&self) -> Result<Vec<WireguardPeer>, sqlx::Error> {
|
||||
sqlx::query_as!(
|
||||
WireguardPeer,
|
||||
r#"
|
||||
SELECT *
|
||||
FROM wireguard_peer;
|
||||
"#,
|
||||
)
|
||||
.fetch_all(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Retrieve the wireguard peer with the provided public key from the storage.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `public_key`: the unique public key of the wireguard peer.
|
||||
pub(crate) async fn remove_peer(&self, public_key: &str) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM wireguard_peer
|
||||
WHERE public_key = ?
|
||||
"#,
|
||||
public_key,
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{v6, v7};
|
||||
|
||||
impl From<v7::response::StaticConnectFailureReason> for v6::response::StaticConnectFailureReason {
|
||||
fn from(failure: v7::response::StaticConnectFailureReason) -> Self {
|
||||
match failure {
|
||||
v7::response::StaticConnectFailureReason::RequestedIpAlreadyInUse => {
|
||||
v6::response::StaticConnectFailureReason::RequestedIpAlreadyInUse
|
||||
}
|
||||
v7::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse => {
|
||||
v6::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse
|
||||
}
|
||||
v7::response::StaticConnectFailureReason::OutOfDateTimestamp => {
|
||||
v6::response::StaticConnectFailureReason::Other("out of date timestamp".to_string())
|
||||
}
|
||||
v7::response::StaticConnectFailureReason::Other(reason) => {
|
||||
v6::response::StaticConnectFailureReason::Other(reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<v7::response::DynamicConnectFailureReason> for v6::response::DynamicConnectFailureReason {
|
||||
fn from(failure: v7::response::DynamicConnectFailureReason) -> Self {
|
||||
match failure {
|
||||
v7::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse => {
|
||||
v6::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse
|
||||
}
|
||||
v7::response::DynamicConnectFailureReason::NoAvailableIp => {
|
||||
v6::response::DynamicConnectFailureReason::NoAvailableIp
|
||||
}
|
||||
v7::response::DynamicConnectFailureReason::Other(err) => {
|
||||
v6::response::DynamicConnectFailureReason::Other(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<v7::response::InfoResponseReply> for v6::response::InfoResponseReply {
|
||||
fn from(reply: v7::response::InfoResponseReply) -> Self {
|
||||
match reply {
|
||||
v7::response::InfoResponseReply::Generic { msg } => {
|
||||
v6::response::InfoResponseReply::Generic { msg }
|
||||
}
|
||||
v7::response::InfoResponseReply::VersionMismatch {
|
||||
request_version,
|
||||
response_version,
|
||||
} => v6::response::InfoResponseReply::VersionMismatch {
|
||||
request_version,
|
||||
response_version,
|
||||
},
|
||||
v7::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst } => {
|
||||
v6::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<v7::response::InfoLevel> for v6::response::InfoLevel {
|
||||
fn from(level: v7::response::InfoLevel) -> Self {
|
||||
match level {
|
||||
v7::response::InfoLevel::Info => v6::response::InfoLevel::Info,
|
||||
v7::response::InfoLevel::Warn => v6::response::InfoLevel::Warn,
|
||||
v7::response::InfoLevel::Error => v6::response::InfoLevel::Error,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
pub mod conversion;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
|
||||
@@ -198,17 +198,6 @@ impl IpPacketRequestData {
|
||||
| IpPacketRequestData::Health(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signable_request(&self) -> Option<Result<Vec<u8>, SignatureError>> {
|
||||
match self {
|
||||
IpPacketRequestData::StaticConnect(request) => Some(request.request()),
|
||||
IpPacketRequestData::DynamicConnect(request) => Some(request.request()),
|
||||
IpPacketRequestData::Disconnect(request) => Some(request.request()),
|
||||
IpPacketRequestData::Data(_) => None,
|
||||
IpPacketRequestData::Ping(_) => None,
|
||||
IpPacketRequestData::Health(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A static connect request is when the client provides the internal IP address it will use on the
|
||||
|
||||
@@ -7,7 +7,7 @@ license.workspace = true
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bip32 = { workspace = true, features = ["secp256k1", "std"] }
|
||||
bip32 = { workspace = true }
|
||||
k256 = { workspace = true }
|
||||
ledger-transport = { workspace = true }
|
||||
ledger-transport-hid = { workspace = true }
|
||||
|
||||
@@ -57,7 +57,7 @@ impl PacketListener {
|
||||
// cloning the arc as each accepted socket is handled in separate task
|
||||
let connection_handler = Arc::clone(&self.connection_handler);
|
||||
let mut handler_shutdown_listener = self.shutdown.clone();
|
||||
handler_shutdown_listener.disarm();
|
||||
handler_shutdown_listener.mark_as_success();
|
||||
|
||||
tokio::select! {
|
||||
socket = listener.accept() => {
|
||||
|
||||
@@ -245,7 +245,7 @@ impl VerlocMeasurer {
|
||||
}
|
||||
|
||||
let mut shutdown_listener = self.shutdown_listener.clone().named("VerlocMeasurement");
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
|
||||
for chunk in nodes_to_test.chunks(self.config.tested_nodes_batch_size) {
|
||||
let mut chunk_results = Vec::with_capacity(chunk.len());
|
||||
|
||||
@@ -84,7 +84,7 @@ impl PacketSender {
|
||||
tested_node: TestedNode,
|
||||
) -> Result<VerlocMeasurement, RttError> {
|
||||
let mut shutdown_listener = self.shutdown_listener.fork(tested_node.address.to_string());
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
|
||||
let mut conn = match tokio::time::timeout(
|
||||
self.connection_timeout,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "nym-mobile-storage"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -2,24 +2,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// Specifies the maximum validity of the issued ticketbooks.
|
||||
pub const TICKETBOOK_VALIDITY_DAYS: u32 = 7;
|
||||
pub const TICKETBOOK_VALIDITY_DAYS: u64 = 7;
|
||||
|
||||
/// Specifies the number of tickets in each issued ticketbook.
|
||||
pub const TICKETBOOK_SIZE: u64 = 50;
|
||||
|
||||
/// This type is defined mostly for the purposes of having constants (like sizes) associated with given variants
|
||||
/// It's not meant to be serialised or have any fancy traits defined on it (in this crate)
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum TicketTypeRepr {
|
||||
pub enum TicketbookType {
|
||||
#[default]
|
||||
V1MixnetEntry = 0,
|
||||
V1MixnetExit = 1,
|
||||
V1WireguardEntry = 2,
|
||||
V1WireguardExit = 3,
|
||||
MixnetEntry = 0,
|
||||
MixnetExit = 1,
|
||||
WireguardEntry = 2,
|
||||
WireguardExit = 3,
|
||||
}
|
||||
|
||||
impl TicketTypeRepr {
|
||||
impl TicketbookType {
|
||||
pub const WIREGUARD_ENTRY_TICKET_SIZE: u64 = 500 * 1024 * 1024; // 500 MB
|
||||
|
||||
// TBD:
|
||||
@@ -30,10 +28,10 @@ impl TicketTypeRepr {
|
||||
/// How much bandwidth (in bytes) one ticket can grant
|
||||
pub const fn bandwidth_value(&self) -> u64 {
|
||||
match self {
|
||||
TicketTypeRepr::V1MixnetEntry => Self::MIXNET_ENTRY_TICKET_SIZE,
|
||||
TicketTypeRepr::V1MixnetExit => Self::MIXNET_EXIT_TICKET_SIZE,
|
||||
TicketTypeRepr::V1WireguardEntry => Self::WIREGUARD_ENTRY_TICKET_SIZE,
|
||||
TicketTypeRepr::V1WireguardExit => Self::WIREGUARD_EXIT_TICKET_SIZE,
|
||||
TicketbookType::MixnetEntry => Self::MIXNET_ENTRY_TICKET_SIZE,
|
||||
TicketbookType::MixnetExit => Self::MIXNET_EXIT_TICKET_SIZE,
|
||||
TicketbookType::WireguardEntry => Self::WIREGUARD_ENTRY_TICKET_SIZE,
|
||||
TicketbookType::WireguardExit => Self::WIREGUARD_EXIT_TICKET_SIZE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
pub mod constants;
|
||||
pub mod ecash;
|
||||
|
||||
// if you haven't read the Cargo.toml file, the reason for all the feature-locking is that
|
||||
// this crate is imported into the ecash contract
|
||||
//
|
||||
// so if you're thinking of adding a new thing, consider feature-locking it and then just adding it to default feature
|
||||
|
||||
#[cfg(all(feature = "env", feature = "network"))]
|
||||
pub mod env_setup;
|
||||
pub mod mainnet;
|
||||
|
||||
@@ -32,7 +32,6 @@ pub const NYXD_URL: &str = "https://rpc.nymtech.net";
|
||||
pub const NYM_API: &str = "https://validator.nymtech.net/api/";
|
||||
pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket";
|
||||
pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
|
||||
pub const NYM_VPN_API: &str = "https://nymvpn.net/api/";
|
||||
|
||||
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
|
||||
pub const EXIT_POLICY_URL: &str =
|
||||
@@ -125,7 +124,6 @@ pub fn export_to_env() {
|
||||
set_var_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
|
||||
set_var_to_default(var_names::EXPLORER_API, EXPLORER_API);
|
||||
set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
|
||||
set_var_to_default(var_names::NYM_VPN_API, NYM_VPN_API);
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "env", feature = "network"))]
|
||||
|
||||
@@ -33,7 +33,6 @@ pub struct NymNetworkDetails {
|
||||
pub endpoints: Vec<ValidatorDetails>,
|
||||
pub contracts: NymContracts,
|
||||
pub explorer_api: Option<String>,
|
||||
pub nym_vpn_api_url: Option<String>,
|
||||
}
|
||||
|
||||
// by default we assume the same defaults as mainnet, i.e. same prefixes and denoms
|
||||
@@ -63,7 +62,6 @@ impl NymNetworkDetails {
|
||||
endpoints: Default::default(),
|
||||
contracts: Default::default(),
|
||||
explorer_api: Default::default(),
|
||||
nym_vpn_api_url: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +120,6 @@ impl NymNetworkDetails {
|
||||
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
|
||||
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
|
||||
.with_explorer_api(get_optional_env(var_names::EXPLORER_API))
|
||||
.with_nym_vpn_api_url(get_optional_env(var_names::NYM_VPN_API))
|
||||
}
|
||||
|
||||
pub fn new_mainnet() -> Self {
|
||||
@@ -150,7 +147,6 @@ impl NymNetworkDetails {
|
||||
),
|
||||
},
|
||||
explorer_api: parse_optional_str(mainnet::EXPLORER_API),
|
||||
nym_vpn_api_url: parse_optional_str(mainnet::NYM_VPN_API),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,19 +255,6 @@ impl NymNetworkDetails {
|
||||
self.explorer_api = endpoint.map(Into::into);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_nym_vpn_api_url<S: Into<String>>(mut self, endpoint: Option<S>) -> Self {
|
||||
self.nym_vpn_api_url = endpoint.map(Into::into);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn nym_vpn_api_url(&self) -> Option<Url> {
|
||||
self.nym_vpn_api_url.as_ref().map(|url| {
|
||||
url.parse()
|
||||
.expect("the provided nym-vpn api url is invalid!")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -24,7 +24,6 @@ pub const NYM_API: &str = "NYM_API";
|
||||
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
|
||||
pub const EXPLORER_API: &str = "EXPLORER_API";
|
||||
pub const EXIT_POLICY_URL: &str = "EXIT_POLICY";
|
||||
pub const NYM_VPN_API: &str = "NYM_VPN_API";
|
||||
|
||||
pub const DKG_TIME_CONFIGURATION: &str = "DKG_TIME_CONFIGURATION";
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ fn bench_coin_signing(c: &mut Criterion) {
|
||||
|
||||
// ISSUING AUTHORITY BENCHMARK: issue a set of (partial) signatures for coin indices
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[IssuingAuthority] sign_coin_indices_L_{}",
|
||||
params.get_total_coins()
|
||||
),
|
||||
@@ -47,7 +47,7 @@ fn bench_coin_signing(c: &mut Criterion) {
|
||||
verify_coin_indices_signatures(&verification_key, &vk_i_auth, &partial_signatures).is_ok()
|
||||
);
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] verify_coin_indices_signatures_L_{}",
|
||||
params.get_total_coins()
|
||||
),
|
||||
@@ -99,7 +99,7 @@ fn bench_aggregate_coin_indices_signatures(c: &mut Criterion) {
|
||||
|
||||
// CLIENT: verify all the partial signature vectors and aggregate into a single vector of signed coin indices
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] aggregate_coin_indices_signatures_from_{}_issuing_authorities_L_{}",
|
||||
authorities_keypairs.len(),
|
||||
params.get_total_coins(),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use itertools::izip;
|
||||
use nym_compact_ecash::identify::{identify, IdentifyResult};
|
||||
use nym_compact_ecash::scheme::expiration_date_signatures::date_scalar;
|
||||
use nym_compact_ecash::scheme::keygen::SecretKeyAuth;
|
||||
use nym_compact_ecash::setup::Parameters;
|
||||
use nym_compact_ecash::tests::helpers::{
|
||||
@@ -14,7 +15,6 @@ use nym_compact_ecash::{
|
||||
ttp_keygen, withdrawal_request, PartialWallet, PayInfo, PublicKeyUser, SecretKeyUser,
|
||||
VerificationKeyAuth,
|
||||
};
|
||||
use nym_network_defaults::TicketTypeRepr;
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
struct BenchCase {
|
||||
@@ -30,14 +30,13 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
// group.sample_size(300);
|
||||
// group.measurement_time(Duration::from_secs(1500));
|
||||
|
||||
let spend_date = 1701907200; // Dec 07 2023 00:00:00
|
||||
let expiration_date = 1702166400; // Dec 10 2023 00:00:00
|
||||
let encoded_ticket_type = TicketTypeRepr::default() as u8;
|
||||
let expiration_date = 1703721600; // Dec 28 2023
|
||||
let spend_date = 1701907200; // Dec 07 2023
|
||||
|
||||
let case = BenchCase {
|
||||
num_authorities: 100,
|
||||
threshold_p: 0.7,
|
||||
ll: 50,
|
||||
ll: 1000,
|
||||
spend_vv: 1,
|
||||
case_nr_pub_keys: 99,
|
||||
};
|
||||
@@ -84,29 +83,15 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
.unwrap();
|
||||
|
||||
// ISSUANCE PHASE
|
||||
let (req, req_info) = withdrawal_request(
|
||||
user_keypair.secret_key(),
|
||||
expiration_date,
|
||||
encoded_ticket_type,
|
||||
)
|
||||
.unwrap();
|
||||
let (req, req_info) = withdrawal_request(user_keypair.secret_key(), expiration_date).unwrap();
|
||||
|
||||
// CLIENT BENCHMARK: prepare a single withdrawal request
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] withdrawal_request_{}_authorities_{}_L_{}_threshold",
|
||||
case.num_authorities, case.ll, case.threshold_p,
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
withdrawal_request(
|
||||
user_keypair.secret_key(),
|
||||
expiration_date,
|
||||
encoded_ticket_type,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
},
|
||||
|b| b.iter(|| withdrawal_request(user_keypair.secret_key(), expiration_date).unwrap()),
|
||||
);
|
||||
|
||||
// ISSUING AUTHRORITY BENCHMARK: Benchmark the issue function
|
||||
@@ -114,7 +99,7 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let keypair = authorities_keypairs.choose(&mut rng).unwrap();
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Issuing Authority] issue_partial_wallet_with_L_{}",
|
||||
case.ll,
|
||||
),
|
||||
@@ -125,7 +110,6 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
user_keypair.public_key(),
|
||||
&req,
|
||||
expiration_date,
|
||||
encoded_ticket_type,
|
||||
)
|
||||
})
|
||||
},
|
||||
@@ -138,7 +122,6 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
user_keypair.public_key(),
|
||||
&req,
|
||||
expiration_date,
|
||||
encoded_ticket_type,
|
||||
);
|
||||
wallet_blinded_signatures.push(blind_signature.unwrap());
|
||||
}
|
||||
@@ -147,7 +130,7 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
let w = wallet_blinded_signatures.first().unwrap();
|
||||
let vk = verification_keys_auth.first().unwrap();
|
||||
group.bench_function(
|
||||
format!("[Client] issue_verify_a_partial_wallet_with_L_{}", case.ll,),
|
||||
&format!("[Client] issue_verify_a_partial_wallet_with_L_{}", case.ll,),
|
||||
|b| b.iter(|| issue_verify(vk, user_keypair.secret_key(), w, &req_info, 1).unwrap()),
|
||||
);
|
||||
|
||||
@@ -163,7 +146,7 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
|
||||
// CLIENT BENCHMARK: aggregating all partial wallets
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] aggregate_wallets_with_L_{}_threshold_{}",
|
||||
case.ll, case.threshold_p,
|
||||
),
|
||||
@@ -196,7 +179,7 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
};
|
||||
// CLIENT BENCHMARK: spend a single coin from the wallet
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] spend_a_single_coin_L_{}_threshold_{}",
|
||||
case.ll, case.threshold_p,
|
||||
),
|
||||
@@ -233,14 +216,14 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
|
||||
// MERCHANT BENCHMARK: verify whether the submitted payment is legit
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Merchant] spend_verify_of_a_single_payment_L_{}_threshold_{}",
|
||||
case.ll, case.threshold_p,
|
||||
),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
payment
|
||||
.spend_verify(&verification_key, &pay_info, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info, date_scalar(spend_date))
|
||||
.unwrap()
|
||||
})
|
||||
},
|
||||
@@ -280,7 +263,7 @@ fn bench_compact_ecash(c: &mut Criterion) {
|
||||
|
||||
// MERCHANT BENCHMARK: identify double spending
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Merchant] identify_L_{}_threshold_{}_spend_vv_{}_pks_{}",
|
||||
case.ll,
|
||||
case.threshold_p,
|
||||
|
||||
@@ -21,7 +21,7 @@ fn bench_partial_sign_expiration_date(c: &mut Criterion) {
|
||||
|
||||
// ISSUING AUTHORITY BENCHMARK: issue a set of (partial) signatures for a given expiration date
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[IssuingAuthority] sign_expiration_date_{}_validity_period",
|
||||
constants::CRED_VALIDITY_PERIOD_DAYS,
|
||||
),
|
||||
@@ -31,7 +31,7 @@ fn bench_partial_sign_expiration_date(c: &mut Criterion) {
|
||||
// CLIENT: verify the correctness of the set of (partial) signatures for a given expiration date
|
||||
assert!(verify_valid_dates_signatures(&vk_i_auth, &partial_exp_sig, expiration_date).is_ok());
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] verify_valid_dates_signatures_{}_validity_period",
|
||||
constants::CRED_VALIDITY_PERIOD_DAYS,
|
||||
),
|
||||
@@ -78,7 +78,7 @@ fn bench_aggregate_expiration_date_signatures(c: &mut Criterion) {
|
||||
|
||||
// CLIENT: verify all the partial signature vectors and aggregate into a single vector of signed valid dates
|
||||
group.bench_function(
|
||||
format!(
|
||||
&format!(
|
||||
"[Client] aggregate_expiration_signatures_from_{}_issuing_authorities_{}_validity_period",
|
||||
constants::CRED_VALIDITY_PERIOD_DAYS, authorities_keypairs.len(),
|
||||
),
|
||||
|
||||
@@ -9,9 +9,9 @@ pub const PUBLIC_ATTRIBUTES_LEN: usize = 2; //expiration date and ticket type
|
||||
pub const PRIVATE_ATTRIBUTES_LEN: usize = 2; //user and wallet secret
|
||||
pub const ATTRIBUTES_LEN: usize = PUBLIC_ATTRIBUTES_LEN + PRIVATE_ATTRIBUTES_LEN; // number of attributes encoded in a single zk-nym credential
|
||||
|
||||
pub const CRED_VALIDITY_PERIOD_DAYS: u32 = TICKETBOOK_VALIDITY_DAYS;
|
||||
pub const CRED_VALIDITY_PERIOD_DAYS: u64 = TICKETBOOK_VALIDITY_DAYS;
|
||||
|
||||
pub(crate) const SECONDS_PER_DAY: u32 = 86400;
|
||||
pub(crate) const SECONDS_PER_DAY: u64 = 86400;
|
||||
|
||||
/// Total number of tickets in each issued ticket book.
|
||||
pub const NB_TICKETS: u64 = TICKETBOOK_SIZE;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::utils::try_deserialize_g1_projective;
|
||||
use crate::{CompactEcashError, EncodedDate, EncodedTicketType};
|
||||
use bls12_381::{G1Projective, Scalar};
|
||||
use crate::CompactEcashError;
|
||||
use bls12_381::G1Projective;
|
||||
use group::Curve;
|
||||
use std::any::{type_name, Any};
|
||||
|
||||
@@ -35,27 +35,3 @@ pub(crate) fn recover_g1_tuple<T: Any>(
|
||||
|
||||
Ok((first, second))
|
||||
}
|
||||
|
||||
pub fn date_scalar(date: EncodedDate) -> Scalar {
|
||||
Scalar::from(date as u64)
|
||||
}
|
||||
|
||||
// TODO: this will not work for **all** scalars,
|
||||
// but timestamps have extremely (relatively speaking) limited range,
|
||||
// so this should be fine
|
||||
pub(crate) fn scalar_date(scalar: &Scalar) -> EncodedDate {
|
||||
let b = scalar.to_bytes();
|
||||
u64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]) as EncodedDate
|
||||
}
|
||||
|
||||
pub fn type_scalar(t_type: EncodedTicketType) -> Scalar {
|
||||
Scalar::from(t_type as u64)
|
||||
}
|
||||
|
||||
// TODO: this will not work for **all** scalars,
|
||||
// but ticket types have extremely (relatively speaking) limited range,
|
||||
// so this should be fine
|
||||
pub(crate) fn scalar_type(scalar: &Scalar) -> EncodedTicketType {
|
||||
let b = scalar.to_bytes();
|
||||
u64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]]) as EncodedTicketType
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ pub use crate::error::CompactEcashError;
|
||||
pub use crate::traits::Bytable;
|
||||
pub use bls12_381::G1Projective;
|
||||
pub use common_types::{BlindedSignature, Signature};
|
||||
pub use helpers::{date_scalar, type_scalar};
|
||||
pub use scheme::aggregation::aggregate_verification_keys;
|
||||
pub use scheme::aggregation::aggregate_wallets;
|
||||
pub use scheme::identify;
|
||||
@@ -43,8 +42,6 @@ mod traits;
|
||||
pub mod utils;
|
||||
|
||||
pub type Attribute = Scalar;
|
||||
pub type EncodedTicketType = u8;
|
||||
pub type EncodedDate = u32;
|
||||
|
||||
pub fn ecash_parameters() -> &'static setup::Parameters {
|
||||
static ECASH_PARAMS: OnceLock<setup::Parameters> = OnceLock::new();
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use core::iter::Sum;
|
||||
use core::ops::Mul;
|
||||
|
||||
use bls12_381::{G2Prepared, G2Projective, Scalar};
|
||||
use group::Curve;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::common_types::{PartialSignature, Signature, SignatureShare, SignerIndex};
|
||||
use crate::error::{CompactEcashError, Result};
|
||||
use crate::helpers::{scalar_date, scalar_type};
|
||||
use crate::scheme::expiration_date_signatures::scalar_date;
|
||||
use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth};
|
||||
use crate::scheme::withdrawal::RequestInfo;
|
||||
use crate::scheme::{PartialWallet, Wallet, WalletSignatures};
|
||||
use crate::utils::{check_bilinear_pairing, perform_lagrangian_interpolation_at_origin};
|
||||
use crate::utils::{
|
||||
check_bilinear_pairing, perform_lagrangian_interpolation_at_origin, scalar_type,
|
||||
};
|
||||
use crate::{ecash_group_parameters, Attribute};
|
||||
use bls12_381::{G2Prepared, G2Projective, Scalar};
|
||||
use core::iter::Sum;
|
||||
use core::ops::Mul;
|
||||
use group::Curve;
|
||||
use itertools::Itertools;
|
||||
|
||||
pub(crate) trait Aggregatable: Sized {
|
||||
fn aggregate(aggregatable: &[Self], indices: Option<&[SignerIndex]>) -> Result<Self>;
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::common_types::{Signature, SignerIndex};
|
||||
use crate::constants;
|
||||
use crate::error::{CompactEcashError, Result};
|
||||
use crate::helpers::date_scalar;
|
||||
use crate::scheme::keygen::{SecretKeyAuth, VerificationKeyAuth};
|
||||
use crate::utils::generate_lagrangian_coefficients_at_origin;
|
||||
use crate::utils::{batch_verify_signatures, hash_g1};
|
||||
use crate::{constants, EncodedDate};
|
||||
use bls12_381::{G1Projective, Scalar};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -20,8 +19,8 @@ pub type PartialExpirationDateSignature = ExpirationDateSignature;
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct AnnotatedExpirationDateSignature {
|
||||
pub signature: ExpirationDateSignature,
|
||||
pub expiration_timestamp: EncodedDate,
|
||||
pub spending_timestamp: EncodedDate,
|
||||
pub expiration_timestamp: u64,
|
||||
pub spending_timestamp: u64,
|
||||
}
|
||||
|
||||
impl Borrow<ExpirationDateSignature> for AnnotatedExpirationDateSignature {
|
||||
@@ -67,17 +66,17 @@ where
|
||||
/// The validity period is determined by the constant `CRED_VALIDITY_PERIOD` in the `constants` module.
|
||||
pub fn sign_expiration_date(
|
||||
sk_auth: &SecretKeyAuth,
|
||||
expiration_unix_timestamp: EncodedDate,
|
||||
expiration_unix_timestamp: u64,
|
||||
) -> Result<Vec<AnnotatedExpirationDateSignature>> {
|
||||
if sk_auth.ys.len() < 3 {
|
||||
return Err(CompactEcashError::KeyTooShort);
|
||||
}
|
||||
let m0: Scalar = date_scalar(expiration_unix_timestamp);
|
||||
let m0: Scalar = Scalar::from(expiration_unix_timestamp);
|
||||
let m2: Scalar = constants::TYPE_EXP;
|
||||
|
||||
let partial_s_exponent = sk_auth.x + sk_auth.ys[0] * m0 + sk_auth.ys[2] * m2;
|
||||
|
||||
let sign_expiration = |offset: u32| {
|
||||
let sign_expiration = |offset: u64| {
|
||||
// we produce tuples of (assuming CRED_VALIDITY_PERIOD_DAYS = 30):
|
||||
// (expiration, expiration - 29)
|
||||
// (expiration, expiration - 28)
|
||||
@@ -85,7 +84,7 @@ pub fn sign_expiration_date(
|
||||
// (expiration, expiration)
|
||||
let spending_unix_timestamp = expiration_unix_timestamp
|
||||
- ((constants::CRED_VALIDITY_PERIOD_DAYS - offset - 1) * constants::SECONDS_PER_DAY);
|
||||
let m1: Scalar = date_scalar(spending_unix_timestamp);
|
||||
let m1: Scalar = Scalar::from(spending_unix_timestamp);
|
||||
// Compute the hash
|
||||
let h = hash_g1([m0.to_bytes(), m1.to_bytes()].concat());
|
||||
// Sign the attributes by performing scalar-point multiplications and accumulating the result
|
||||
@@ -137,22 +136,22 @@ pub fn sign_expiration_date(
|
||||
pub fn verify_valid_dates_signatures<B>(
|
||||
vk: &VerificationKeyAuth,
|
||||
signatures: &[B],
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
) -> Result<()>
|
||||
where
|
||||
B: Borrow<ExpirationDateSignature>,
|
||||
{
|
||||
let m0: Scalar = date_scalar(expiration_date);
|
||||
let m0: Scalar = Scalar::from(expiration_date);
|
||||
let m2: Scalar = constants::TYPE_EXP;
|
||||
|
||||
let partially_signed = vk.alpha + vk.beta_g2[0] * m0 + vk.beta_g2[2] * m2;
|
||||
let mut pairing_terms = Vec::with_capacity(signatures.len());
|
||||
|
||||
for (i, sig) in signatures.iter().enumerate() {
|
||||
let l = i as u32;
|
||||
let l = i as u64;
|
||||
let valid_date = expiration_date
|
||||
- ((constants::CRED_VALIDITY_PERIOD_DAYS - l - 1) * constants::SECONDS_PER_DAY);
|
||||
let m1: Scalar = date_scalar(valid_date);
|
||||
let m1: Scalar = Scalar::from(valid_date);
|
||||
|
||||
// Compute the hash
|
||||
let h = hash_g1([m0.to_bytes(), m1.to_bytes()].concat());
|
||||
@@ -200,7 +199,7 @@ where
|
||||
///
|
||||
fn _aggregate_expiration_signatures<B>(
|
||||
vk: &VerificationKeyAuth,
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
signatures_shares: &[ExpirationDateSignatureShare<B>],
|
||||
validate_shares: bool,
|
||||
) -> Result<Vec<ExpirationDateSignature>>
|
||||
@@ -245,12 +244,12 @@ where
|
||||
let mut aggregated_date_signatures: Vec<ExpirationDateSignature> =
|
||||
Vec::with_capacity(constants::CRED_VALIDITY_PERIOD_DAYS as usize);
|
||||
|
||||
let m0: Scalar = date_scalar(expiration_date);
|
||||
let m0: Scalar = Scalar::from(expiration_date);
|
||||
|
||||
for l in 0..constants::CRED_VALIDITY_PERIOD_DAYS {
|
||||
let valid_date = expiration_date
|
||||
- ((constants::CRED_VALIDITY_PERIOD_DAYS - l - 1) * constants::SECONDS_PER_DAY);
|
||||
let m1: Scalar = date_scalar(valid_date);
|
||||
let m1: Scalar = Scalar::from(valid_date);
|
||||
// Compute the hash
|
||||
let h = hash_g1([m0.to_bytes(), m1.to_bytes()].concat());
|
||||
|
||||
@@ -300,7 +299,7 @@ where
|
||||
///
|
||||
pub fn aggregate_expiration_signatures<B>(
|
||||
vk: &VerificationKeyAuth,
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
signatures_shares: &[ExpirationDateSignatureShare<B>],
|
||||
) -> Result<Vec<ExpirationDateSignature>>
|
||||
where
|
||||
@@ -315,7 +314,7 @@ where
|
||||
/// It further annotates the result with timestamp information
|
||||
pub fn aggregate_annotated_expiration_signatures(
|
||||
vk: &VerificationKeyAuth,
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
signatures_shares: &[ExpirationDateSignatureShare<AnnotatedExpirationDateSignature>],
|
||||
) -> Result<Vec<AnnotatedExpirationDateSignature>> {
|
||||
// it's sufficient to just verify the first share as if the rest of them don't match,
|
||||
@@ -333,7 +332,7 @@ pub fn aggregate_annotated_expiration_signatures(
|
||||
return Err(CompactEcashError::ExpirationDateSignatureVerification);
|
||||
}
|
||||
|
||||
let l = i as u32;
|
||||
let l = i as u64;
|
||||
let expected_spending = sig.expiration_timestamp
|
||||
- ((constants::CRED_VALIDITY_PERIOD_DAYS - l - 1) * constants::SECONDS_PER_DAY);
|
||||
|
||||
@@ -362,7 +361,7 @@ pub fn aggregate_annotated_expiration_signatures(
|
||||
/// It is expected the caller has already pre-validated them via manual calls to `verify_valid_dates_signatures`
|
||||
pub fn unchecked_aggregate_expiration_signatures(
|
||||
vk: &VerificationKeyAuth,
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
signatures_shares: &[ExpirationDateSignatureShare],
|
||||
) -> Result<Vec<ExpirationDateSignature>> {
|
||||
_aggregate_expiration_signatures(vk, expiration_date, signatures_shares, false)
|
||||
@@ -384,13 +383,13 @@ pub fn unchecked_aggregate_expiration_signatures(
|
||||
/// If a valid index is found, returns `Ok(index)`. If no valid index is found
|
||||
/// (i.e., `spend_date` is earlier than `expiration_date - 30`), returns `Err(InvalidDateError)`.
|
||||
///
|
||||
pub fn find_index(spend_date: EncodedDate, expiration_date: EncodedDate) -> Result<usize> {
|
||||
pub fn find_index(spend_date: u64, expiration_date: u64) -> Result<usize> {
|
||||
let start_date =
|
||||
expiration_date - ((constants::CRED_VALIDITY_PERIOD_DAYS - 1) * constants::SECONDS_PER_DAY);
|
||||
|
||||
if spend_date >= start_date {
|
||||
let index_a = ((spend_date - start_date) / constants::SECONDS_PER_DAY) as usize;
|
||||
if index_a as u32 >= constants::CRED_VALIDITY_PERIOD_DAYS {
|
||||
if index_a as u64 >= constants::CRED_VALIDITY_PERIOD_DAYS {
|
||||
Err(CompactEcashError::SpendDateTooLate)
|
||||
} else {
|
||||
Ok(index_a)
|
||||
@@ -400,6 +399,18 @@ pub fn find_index(spend_date: EncodedDate, expiration_date: EncodedDate) -> Resu
|
||||
}
|
||||
}
|
||||
|
||||
pub fn date_scalar(date: u64) -> Scalar {
|
||||
Scalar::from(date)
|
||||
}
|
||||
|
||||
// TODO: this will not work for **all** scalars,
|
||||
// but timestamps have extremely (relatively speaking) limited range,
|
||||
// so this should be fine
|
||||
pub fn scalar_date(scalar: &Scalar) -> u64 {
|
||||
let b = scalar.to_bytes();
|
||||
u64::from_le_bytes([b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -54,6 +54,7 @@ pub fn identify(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::scheme::expiration_date_signatures::date_scalar;
|
||||
use crate::scheme::identify::{identify, IdentifyResult};
|
||||
use crate::scheme::keygen::{PublicKeyUser, SecretKeyAuth, SecretKeyUser};
|
||||
use crate::setup::Parameters;
|
||||
@@ -164,12 +165,12 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment1
|
||||
.spend_verify(&verification_key, &pay_info1, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info1, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let payment2 = payment1.clone();
|
||||
assert!(payment2
|
||||
.spend_verify(&verification_key, &pay_info1, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info1, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let identify_result = identify(&payment1, &payment2, pay_info1, pay_info1);
|
||||
@@ -274,7 +275,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment1
|
||||
.spend_verify(&verification_key, &pay_info1, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info1, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let pay_info2 = PayInfo {
|
||||
@@ -294,7 +295,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment2
|
||||
.spend_verify(&verification_key, &pay_info2, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info2, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let identify_result = identify(&payment1, &payment2, pay_info1, pay_info2);
|
||||
@@ -410,7 +411,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment1
|
||||
.spend_verify(&verification_key, &pay_info1, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info1, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
// let's reverse the spending counter in the wallet to create a double spending payment
|
||||
@@ -434,7 +435,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment2
|
||||
.spend_verify(&verification_key, &pay_info2, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info2, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let identify_result = identify(&payment1, &payment2, pay_info1, pay_info2);
|
||||
@@ -554,7 +555,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert!(payment1
|
||||
.spend_verify(&verification_key, &pay_info1, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info1, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
// let's reverse the spending counter in the wallet to create a double spending payment
|
||||
|
||||
@@ -97,6 +97,10 @@ impl SecretKeyAuth {
|
||||
self.ys.len()
|
||||
}
|
||||
|
||||
pub(crate) fn get_y_by_idx(&self, i: usize) -> Option<&Scalar> {
|
||||
self.ys.get(i)
|
||||
}
|
||||
|
||||
pub fn verification_key(&self) -> VerificationKeyAuth {
|
||||
let params = ecash_group_parameters();
|
||||
let g1 = params.gen1();
|
||||
|
||||
@@ -3,18 +3,17 @@
|
||||
|
||||
use crate::common_types::{Signature, SignerIndex};
|
||||
use crate::error::{CompactEcashError, Result};
|
||||
use crate::helpers::{date_scalar, type_scalar};
|
||||
use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness};
|
||||
use crate::scheme::coin_indices_signatures::CoinIndexSignature;
|
||||
use crate::scheme::expiration_date_signatures::{find_index, ExpirationDateSignature};
|
||||
use crate::scheme::expiration_date_signatures::{date_scalar, find_index, ExpirationDateSignature};
|
||||
use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth};
|
||||
use crate::scheme::setup::{GroupParameters, Parameters};
|
||||
use crate::traits::Bytable;
|
||||
use crate::utils::{
|
||||
batch_verify_signatures, check_bilinear_pairing, hash_to_scalar, try_deserialize_scalar,
|
||||
};
|
||||
use crate::Base58;
|
||||
use crate::{constants, ecash_group_parameters};
|
||||
use crate::{Base58, EncodedDate, EncodedTicketType};
|
||||
use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar};
|
||||
use group::Curve;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
@@ -229,7 +228,7 @@ impl Wallet {
|
||||
spend_value: u64,
|
||||
valid_dates_signatures: &[ExpirationDateSignature],
|
||||
coin_indices_signatures: &[CoinIndexSignature],
|
||||
spend_date_timestamp: EncodedDate,
|
||||
spend_date_timestamp: u64,
|
||||
) -> Result<Payment> {
|
||||
self.check_remaining_allowance(params, spend_value)?;
|
||||
|
||||
@@ -270,8 +269,8 @@ pub struct WalletSignatures {
|
||||
#[zeroize(skip)]
|
||||
sig: Signature,
|
||||
v: Scalar,
|
||||
expiration_date_timestamp: EncodedDate,
|
||||
t_type: EncodedTicketType,
|
||||
expiration_date_timestamp: u64,
|
||||
t_type: u64,
|
||||
}
|
||||
|
||||
impl WalletSignatures {
|
||||
@@ -315,8 +314,8 @@ pub fn compute_pay_info_hash(pay_info: &PayInfo, k: u64) -> Scalar {
|
||||
}
|
||||
|
||||
impl WalletSignatures {
|
||||
// signature size (96) + secret size (32) + expiration size (4) + t_type (1)
|
||||
pub const SERIALISED_SIZE: usize = 133;
|
||||
// signature size (96) + secret size (32) + expiration size (8) + t_type (8)
|
||||
pub const SERIALISED_SIZE: usize = 144;
|
||||
|
||||
pub fn signature(&self) -> &Signature {
|
||||
&self.sig
|
||||
@@ -336,8 +335,8 @@ impl WalletSignatures {
|
||||
let mut bytes = [0u8; Self::SERIALISED_SIZE];
|
||||
bytes[0..96].copy_from_slice(&self.sig.to_bytes());
|
||||
bytes[96..128].copy_from_slice(&self.v.to_bytes());
|
||||
bytes[128..132].copy_from_slice(&self.expiration_date_timestamp.to_be_bytes());
|
||||
bytes[132] = self.t_type;
|
||||
bytes[128..136].copy_from_slice(&self.expiration_date_timestamp.to_be_bytes());
|
||||
bytes[136..144].copy_from_slice(&self.t_type.to_be_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
@@ -357,12 +356,15 @@ impl WalletSignatures {
|
||||
let v_bytes: &[u8; 32] = &bytes[96..128].try_into().unwrap();
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let expiration_date_bytes = bytes[128..132].try_into().unwrap();
|
||||
let expiration_date_bytes = bytes[128..136].try_into().unwrap();
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let t_type_bytes = bytes[136..].try_into().unwrap();
|
||||
|
||||
let sig = Signature::try_from(sig_bytes.as_slice())?;
|
||||
let v = Scalar::from_bytes(v_bytes).unwrap();
|
||||
let expiration_date_timestamp = EncodedDate::from_be_bytes(expiration_date_bytes);
|
||||
let t_type = bytes[132];
|
||||
let expiration_date_timestamp = u64::from_be_bytes(expiration_date_bytes);
|
||||
let t_type = u64::from_be_bytes(t_type_bytes);
|
||||
|
||||
Ok(WalletSignatures {
|
||||
sig,
|
||||
@@ -399,7 +401,7 @@ impl WalletSignatures {
|
||||
spend_value: u64,
|
||||
valid_dates_signatures: &[BE],
|
||||
coin_indices_signatures: &[BI],
|
||||
spend_date_timestamp: EncodedDate,
|
||||
spend_date_timestamp: u64,
|
||||
) -> Result<Payment>
|
||||
where
|
||||
BI: Borrow<CoinIndexSignature>,
|
||||
@@ -594,7 +596,7 @@ fn pseudorandom_f_g_v(params: &GroupParameters, v: &Scalar, l: u64) -> Result<G1
|
||||
/// * `params` - A reference to the group parameters required for the computation.
|
||||
/// * `verification_key` - The global verification key of the signing authorities.
|
||||
/// * `attributes` - A slice of private attributes associated with the wallet.
|
||||
/// * `blinding_factor` - The blinding factor used to randomise the wallet's signature.
|
||||
/// * `blinding_factor` - The blinding factor used used to randomise the wallet's signature.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -687,7 +689,7 @@ pub struct Payment {
|
||||
pub aa: Vec<G1Projective>,
|
||||
pub spend_value: u64,
|
||||
pub cc: G1Projective,
|
||||
pub t_type: EncodedTicketType,
|
||||
pub t_type: u64,
|
||||
pub zk_proof: SpendProof,
|
||||
}
|
||||
|
||||
@@ -718,7 +720,7 @@ impl Payment {
|
||||
return Err(CompactEcashError::SpendSignaturesValidity);
|
||||
}
|
||||
|
||||
let kappa_type = self.kappa + verification_key.beta_g2[3] * type_scalar(self.t_type);
|
||||
let kappa_type = self.kappa + verification_key.beta_g2[3] * Scalar::from(self.t_type);
|
||||
if !check_bilinear_pairing(
|
||||
&self.sig.h.to_affine(),
|
||||
&G2Prepared::from(kappa_type.to_affine()),
|
||||
@@ -948,7 +950,7 @@ impl Payment {
|
||||
&self,
|
||||
verification_key: &VerificationKeyAuth,
|
||||
pay_info: &PayInfo,
|
||||
spend_date: EncodedDate,
|
||||
spend_date: Scalar,
|
||||
) -> Result<()> {
|
||||
// check if all serial numbers are different
|
||||
self.no_duplicate_serial_numbers()?;
|
||||
@@ -957,7 +959,7 @@ impl Payment {
|
||||
// Verify whether the payment signature and kappa are correct
|
||||
self.check_signature_validity(verification_key)?;
|
||||
// Verify whether the expiration date signature and kappa_e are correct
|
||||
self.check_exp_signature_validity(verification_key, date_scalar(spend_date))?;
|
||||
self.check_exp_signature_validity(verification_key, spend_date)?;
|
||||
// Verify whether the coin indices signatures and kappa_k are correct
|
||||
self.batch_check_coin_index_signatures(verification_key)?;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
use crate::common_types::{BlindedSignature, Signature, SignerIndex};
|
||||
use crate::error::{CompactEcashError, Result};
|
||||
use crate::helpers::{date_scalar, type_scalar};
|
||||
use crate::proofs::proof_withdrawal::{
|
||||
WithdrawalReqInstance, WithdrawalReqProof, WithdrawalReqWitness,
|
||||
};
|
||||
@@ -11,7 +10,7 @@ use crate::scheme::keygen::{PublicKeyUser, SecretKeyAuth, SecretKeyUser, Verific
|
||||
use crate::scheme::setup::GroupParameters;
|
||||
use crate::scheme::PartialWallet;
|
||||
use crate::utils::{check_bilinear_pairing, hash_g1};
|
||||
use crate::{constants, ecash_group_parameters, Attribute, EncodedDate, EncodedTicketType};
|
||||
use crate::{constants, ecash_group_parameters, Attribute};
|
||||
use bls12_381::{multi_miller_loop, G1Projective, G2Prepared, G2Projective, Scalar};
|
||||
use group::{Curve, Group, GroupEncoding};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -142,25 +141,28 @@ fn compute_private_attribute_commitments(
|
||||
/// openings for private attributes, `v`, and the expiration date.
|
||||
pub fn withdrawal_request(
|
||||
sk_user: &SecretKeyUser,
|
||||
expiration_date: EncodedDate,
|
||||
t_type: EncodedTicketType,
|
||||
expiration_date: u64,
|
||||
t_type: u64,
|
||||
) -> Result<(WithdrawalRequest, RequestInfo)> {
|
||||
let params = ecash_group_parameters();
|
||||
// Generate random and unique wallet secret
|
||||
let v = params.random_scalar();
|
||||
let joined_commitment_opening = params.random_scalar();
|
||||
|
||||
let gamma = params.gammas();
|
||||
let expiration_date = date_scalar(expiration_date);
|
||||
let t_type = type_scalar(t_type);
|
||||
|
||||
// Compute joined commitment for all attributes (public and private)
|
||||
let joined_commitment =
|
||||
params.gen1() * joined_commitment_opening + gamma[0] * sk_user.sk + gamma[1] * v;
|
||||
//SAFETY: params is static with length 3
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let joined_commitment: G1Projective = params.gen1() * joined_commitment_opening
|
||||
+ params.gamma_idx(0).unwrap() * sk_user.sk
|
||||
+ params.gamma_idx(1).unwrap() * v;
|
||||
|
||||
// Compute commitment hash h
|
||||
let joined_commitment_hash =
|
||||
hash_g1((joined_commitment + gamma[2] * expiration_date + gamma[3] * t_type).to_bytes());
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let joined_commitment_hash = hash_g1(
|
||||
(joined_commitment
|
||||
+ params.gamma_idx(2).unwrap() * Scalar::from(expiration_date)
|
||||
+ params.gamma_idx(3).unwrap() * Scalar::from(t_type))
|
||||
.to_bytes(),
|
||||
);
|
||||
|
||||
// Compute Pedersen commitments for private attributes (wallet secret and user's secret)
|
||||
let private_attributes = vec![sk_user.sk, v];
|
||||
@@ -197,8 +199,8 @@ pub fn withdrawal_request(
|
||||
joined_commitment_opening,
|
||||
private_attributes_openings: private_attributes_openings.clone(),
|
||||
wallet_secret: v,
|
||||
expiration_date,
|
||||
t_type,
|
||||
expiration_date: Scalar::from(expiration_date),
|
||||
t_type: Scalar::from(t_type),
|
||||
},
|
||||
))
|
||||
}
|
||||
@@ -220,17 +222,18 @@ pub fn withdrawal_request(
|
||||
pub fn request_verify(
|
||||
req: &WithdrawalRequest,
|
||||
pk_user: PublicKeyUser,
|
||||
expiration_date: EncodedDate,
|
||||
t_type: EncodedTicketType,
|
||||
expiration_date: u64,
|
||||
t_type: u64,
|
||||
) -> Result<()> {
|
||||
let params = ecash_group_parameters();
|
||||
|
||||
let gamma = params.gammas();
|
||||
let expiration_date = date_scalar(expiration_date);
|
||||
let t_type = type_scalar(t_type);
|
||||
|
||||
// Verify the joined commitment hash
|
||||
//SAFETY: params is static with length 3
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let expected_commitment_hash = hash_g1(
|
||||
(req.joined_commitment + gamma[2] * expiration_date + gamma[3] * t_type).to_bytes(),
|
||||
(req.joined_commitment
|
||||
+ params.gamma_idx(2).unwrap() * Scalar::from(expiration_date)
|
||||
+ params.gamma_idx(3).unwrap() * Scalar::from(t_type))
|
||||
.to_bytes(),
|
||||
);
|
||||
if req.joined_commitment_hash != expected_commitment_hash {
|
||||
return Err(CompactEcashError::WithdrawalRequestVerification);
|
||||
@@ -267,10 +270,13 @@ pub fn request_verify(
|
||||
/// authentication secret key index is out of bounds.
|
||||
fn sign_expiration_date(
|
||||
joined_commitment_hash: &G1Projective,
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
sk_auth: &SecretKeyAuth,
|
||||
) -> G1Projective {
|
||||
joined_commitment_hash * (sk_auth.ys[2] * date_scalar(expiration_date))
|
||||
//SAFETY : this fn assumes a long enough key
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let yi = sk_auth.get_y_by_idx(2).unwrap();
|
||||
joined_commitment_hash * (yi * Scalar::from(expiration_date))
|
||||
}
|
||||
|
||||
/// Signs a transaction type using a joined commitment hash and a secret key.
|
||||
@@ -290,10 +296,13 @@ fn sign_expiration_date(
|
||||
/// The resulting G1Projective point representing the signed ticket type.
|
||||
fn sign_t_type(
|
||||
joined_commitment_hash: &G1Projective,
|
||||
t_type: EncodedTicketType,
|
||||
t_type: u64,
|
||||
sk_auth: &SecretKeyAuth,
|
||||
) -> G1Projective {
|
||||
joined_commitment_hash * (sk_auth.ys[3] * type_scalar(t_type))
|
||||
//SAFETY : this fn assumes a long enough key
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let yi = sk_auth.get_y_by_idx(3).unwrap();
|
||||
joined_commitment_hash * (yi * Scalar::from(t_type))
|
||||
}
|
||||
|
||||
/// Issues a blinded signature for a withdrawal request, after verifying its integrity.
|
||||
@@ -318,8 +327,8 @@ pub fn issue(
|
||||
sk_auth: &SecretKeyAuth,
|
||||
pk_user: PublicKeyUser,
|
||||
withdrawal_req: &WithdrawalRequest,
|
||||
expiration_date: EncodedDate,
|
||||
t_type: EncodedTicketType,
|
||||
expiration_date: u64,
|
||||
t_type: u64,
|
||||
) -> Result<BlindedSignature> {
|
||||
// Verify the withdrawal request
|
||||
request_verify(withdrawal_req, pk_user, expiration_date, t_type)?;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
mod tests {
|
||||
use crate::error::Result;
|
||||
use crate::scheme::aggregation::{aggregate_verification_keys, aggregate_wallets};
|
||||
use crate::scheme::expiration_date_signatures::date_scalar;
|
||||
use crate::scheme::keygen::{
|
||||
generate_keypair_user, ttp_keygen, SecretKeyAuth, VerificationKeyAuth,
|
||||
};
|
||||
@@ -124,7 +125,7 @@ mod tests {
|
||||
)?;
|
||||
|
||||
assert!(payment
|
||||
.spend_verify(&verification_key, &pay_info, spend_date)
|
||||
.spend_verify(&verification_key, &pay_info, date_scalar(spend_date))
|
||||
.is_ok());
|
||||
|
||||
let payment_bytes = payment.to_bytes();
|
||||
|
||||
@@ -15,13 +15,12 @@ use crate::scheme::Payment;
|
||||
use crate::setup::Parameters;
|
||||
use crate::{
|
||||
aggregate_verification_keys, aggregate_wallets, constants, generate_keypair_user, issue,
|
||||
issue_verify, withdrawal_request, EncodedDate, EncodedTicketType, PartialWallet, PayInfo,
|
||||
VerificationKeyAuth,
|
||||
issue_verify, withdrawal_request, PartialWallet, PayInfo, VerificationKeyAuth,
|
||||
};
|
||||
use itertools::izip;
|
||||
|
||||
pub fn generate_expiration_date_signatures(
|
||||
expiration_date: EncodedDate,
|
||||
expiration_date: u64,
|
||||
secret_keys_authorities: &[&SecretKeyAuth],
|
||||
verification_keys_auth: &[VerificationKeyAuth],
|
||||
verification_key: &VerificationKeyAuth,
|
||||
@@ -83,8 +82,8 @@ pub fn generate_coin_indices_signatures(
|
||||
pub fn payment_from_keys_and_expiration_date(
|
||||
ecash_keypairs: &Vec<KeyPairAuth>,
|
||||
indices: &[SignerIndex],
|
||||
expiration_date: EncodedDate,
|
||||
t_type: EncodedTicketType,
|
||||
expiration_date: u64,
|
||||
t_type: u64,
|
||||
) -> Result<(Payment, PayInfo)> {
|
||||
let total_coins = 32;
|
||||
let params = Parameters::new(total_coins);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user