diff --git a/Cargo.lock b/Cargo.lock index 0923a3a4f9c..ad525671a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,15 +332,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.3.0", -] - [[package]] name = "autocfg" version = "1.3.0" @@ -553,7 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", + "rand", "rand_core 0.6.4", "serde", "unicode-normalization", @@ -994,15 +985,6 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "colorchoice" version = "1.0.1" @@ -2259,8 +2241,8 @@ dependencies = [ "nym-validator-client", "okapi", "pretty_env_logger", - "rand 0.8.5", - "rand_pcg 0.3.1", + "rand", + "rand_pcg", "rand_seeder", "reqwest 0.12.4", "rocket", @@ -2459,12 +2441,6 @@ dependencies = [ "libc", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "2.0.0" @@ -3345,7 +3321,7 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.3.0", + "autocfg", "hashbrown 0.12.3", "serde", ] @@ -3760,7 +3736,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ - "autocfg 1.3.0", + "autocfg", "scopeguard", ] @@ -3887,7 +3863,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "autocfg 1.3.0", + "autocfg", ] [[package]] @@ -3957,7 +3933,7 @@ dependencies = [ "nym-ordered-buffer", "nym-service-providers-common", "nym-socks5-requests", - "rand 0.8.5", + "rand", "serde", "serde-wasm-bindgen 0.6.5", "thiserror", @@ -4173,7 +4149,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg 1.3.0", + "autocfg", "libm", ] @@ -4257,8 +4233,8 @@ dependencies = [ "nym-vesting-contract-common", "okapi", "pin-project", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "reqwest 0.12.4", "rocket", "rocket_cors", @@ -4344,7 +4320,7 @@ dependencies = [ "nym-types", "nym-wireguard", "nym-wireguard-types", - "rand 0.8.5", + "rand", "serde", "serde_json", "thiserror", @@ -4361,7 +4337,7 @@ dependencies = [ "bincode", "nym-sphinx", "nym-wireguard-types", - "rand 0.8.5", + "rand", "serde", ] @@ -4379,7 +4355,7 @@ dependencies = [ "nym-ecash-time", "nym-network-defaults", "nym-validator-client", - "rand 0.8.5", + "rand", "thiserror", "url", "zeroize", @@ -4453,11 +4429,12 @@ name = "nym-cli-commands" version = "1.0.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64 0.21.7", "bip39", "bs58 0.5.1", "cfg-if", "clap 4.5.7", + "colored", "comfy-table 6.2.0", "cosmrs 0.17.0-pre", "cosmwasm-std", @@ -4490,14 +4467,14 @@ dependencies = [ "nym-types", "nym-validator-client", "nym-vesting-contract-common", - "rand 0.6.5", + "rand", "serde", "serde_json", "tap", "thiserror", "time", "tokio", - "toml 0.5.11", + "toml 0.8.14", "url", "zeroize", ] @@ -4527,7 +4504,7 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "serde_json", "tap", @@ -4578,7 +4555,7 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "serde_json", "sha2 0.10.8", @@ -4658,7 +4635,7 @@ dependencies = [ "nym-bin-common", "nym-node-tester-utils", "nym-node-tester-wasm", - "rand 0.8.5", + "rand", "serde", "serde-wasm-bindgen 0.6.5", "serde_json", @@ -4695,8 +4672,8 @@ dependencies = [ "itertools 0.13.0", "nym-dkg", "nym-pemstore", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "serde", "serde_derive", "sha2 0.9.9", @@ -4742,7 +4719,7 @@ dependencies = [ "itertools 0.12.1", "nym-network-defaults", "nym-pemstore", - "rand 0.8.5", + "rand", "rayon", "serde", "sha2 0.9.9", @@ -4836,7 +4813,7 @@ dependencies = [ "nym-ecash-time", "nym-network-defaults", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "thiserror", "time", @@ -4851,7 +4828,7 @@ dependencies = [ "nym-compact-ecash", "nym-ecash-time", "nym-network-defaults", - "rand 0.8.5", + "rand", "serde", "strum 0.25.0", "thiserror", @@ -4874,8 +4851,8 @@ dependencies = [ "hmac", "nym-pemstore", "nym-sphinx-types", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "serde", "serde_bytes", "subtle-encoding", @@ -4897,8 +4874,8 @@ dependencies = [ "lazy_static", "nym-contracts-common", "nym-pemstore", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rand_core 0.6.4", "serde", "serde_derive", @@ -5028,7 +5005,7 @@ dependencies = [ "nym-wireguard", "nym-wireguard-types", "once_cell", - "rand 0.8.5", + "rand", "serde", "serde_json", "si-scale", @@ -5063,7 +5040,7 @@ dependencies = [ "nym-sphinx", "nym-task", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "si-scale", "thiserror", @@ -5092,7 +5069,7 @@ dependencies = [ "nym-crypto", "nym-pemstore", "nym-sphinx", - "rand 0.8.5", + "rand", "serde", "serde_json", "thiserror", @@ -5192,7 +5169,7 @@ name = "nym-inclusion-probability" version = "0.1.0" dependencies = [ "log", - "rand 0.8.5", + "rand", "thiserror", ] @@ -5205,7 +5182,7 @@ dependencies = [ "nym-bin-common", "nym-crypto", "nym-sphinx", - "rand 0.8.5", + "rand", "serde", "thiserror", "time", @@ -5242,7 +5219,7 @@ dependencies = [ "nym-types", "nym-wireguard", "nym-wireguard-types", - "rand 0.8.5", + "rand", "reqwest 0.12.4", "serde", "serde_json", @@ -5299,7 +5276,7 @@ dependencies = [ "humantime-serde", "log", "nym-contracts-common", - "rand_chacha 0.3.1", + "rand_chacha", "schemars", "serde", "serde-json-wasm", @@ -5342,7 +5319,7 @@ dependencies = [ "nym-topology", "nym-types", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "serde_json", "sysinfo 0.27.8", @@ -5375,7 +5352,7 @@ dependencies = [ "nym-sphinx-types", "nym-task", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "thiserror", "time", @@ -5445,7 +5422,7 @@ dependencies = [ "nym-types", "pretty_env_logger", "publicsuffix", - "rand 0.8.5", + "rand", "regex", "reqwest 0.12.4", "serde", @@ -5492,7 +5469,7 @@ dependencies = [ "nym-types", "nym-wireguard", "nym-wireguard-types", - "rand 0.8.5", + "rand", "semver 1.0.23", "serde", "serde_json", @@ -5526,7 +5503,7 @@ dependencies = [ "nym-task", "nym-wireguard", "nym-wireguard-types", - "rand 0.8.5", + "rand", "serde_json", "thiserror", "time", @@ -5553,7 +5530,7 @@ dependencies = [ "nym-exit-policy", "nym-http-api-client", "nym-wireguard-types", - "rand_chacha 0.3.1", + "rand_chacha", "schemars", "serde", "serde_json", @@ -5574,7 +5551,7 @@ dependencies = [ "nym-sphinx-params", "nym-task", "nym-topology", - "rand 0.8.5", + "rand", "serde", "serde_json", "thiserror", @@ -5589,7 +5566,7 @@ dependencies = [ "futures", "js-sys", "nym-node-tester-utils", - "rand 0.8.5", + "rand", "serde", "serde-wasm-bindgen 0.6.5", "thiserror", @@ -5648,7 +5625,7 @@ dependencies = [ "fastrand 2.1.0", "getrandom", "log", - "rand 0.8.5", + "rand", "rayon", "sphinx-packet", "thiserror", @@ -5697,7 +5674,7 @@ dependencies = [ "nym-validator-client", "parking_lot 0.12.3", "pretty_env_logger", - "rand 0.8.5", + "rand", "reqwest 0.12.4", "tap", "thiserror", @@ -5757,7 +5734,7 @@ dependencies = [ "nym-sphinx", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "serde_json", "tap", @@ -5790,7 +5767,7 @@ dependencies = [ "nym-task", "nym-validator-client", "pin-project", - "rand 0.8.5", + "rand", "reqwest 0.12.4", "schemars", "serde", @@ -5816,7 +5793,7 @@ dependencies = [ "nym-credential-storage", "nym-crypto", "nym-socks5-client-core", - "rand 0.8.5", + "rand", "safer-ffi", "serde", "tokio", @@ -5870,7 +5847,7 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand", "rand_distr", "thiserror", "tokio", @@ -5888,7 +5865,7 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand", "serde", "thiserror", "zeroize", @@ -5900,7 +5877,7 @@ version = "0.1.0" dependencies = [ "nym-crypto", "nym-sphinx-types", - "rand 0.8.5", + "rand", "serde", "thiserror", ] @@ -5916,8 +5893,8 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "serde", "thiserror", "wasm-bindgen", @@ -5931,7 +5908,7 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-params", "nym-sphinx-types", - "rand 0.8.5", + "rand", "thiserror", ] @@ -5948,7 +5925,7 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand", "thiserror", ] @@ -6010,7 +5987,7 @@ dependencies = [ "argon2", "generic-array 0.14.7", "getrandom", - "rand 0.8.5", + "rand", "serde", "serde_json", "thiserror", @@ -6045,7 +6022,7 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-routing", "nym-sphinx-types", - "rand 0.8.5", + "rand", "semver 0.11.0", "serde", "serde_json", @@ -6169,7 +6146,7 @@ dependencies = [ "nym-task", "nym-validator-client", "nyxd-scraper", - "rand_chacha 0.3.1", + "rand_chacha", "serde", "serde_with", "sha2 0.10.8", @@ -6248,7 +6225,7 @@ dependencies = [ "nym-config", "nym-crypto", "nym-network-defaults", - "rand 0.8.5", + "rand", "serde", "serde_json", "sha2 0.10.8", @@ -6458,7 +6435,7 @@ dependencies = [ "once_cell", "opentelemetry_api", "percent-encoding", - "rand 0.8.5", + "rand", "thiserror", "tokio", "tokio-stream", @@ -6771,7 +6748,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ - "autocfg 1.3.0", + "autocfg", "bitflags 1.3.2", "cfg-if", "concurrent-queue", @@ -7025,25 +7002,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg 0.1.2", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.8.5" @@ -7051,20 +7009,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -7075,21 +7023,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.5.1" @@ -7112,60 +7045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", + "rand", ] [[package]] @@ -7186,15 +7066,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "rayon" version = "1.10.0" @@ -7215,15 +7086,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -7481,7 +7343,7 @@ dependencies = [ "num_cpus", "parking_lot 0.12.3", "pin-project-lite", - "rand 0.8.5", + "rand", "ref-cast", "rocket_codegen", "rocket_http", @@ -8254,7 +8116,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "autocfg 1.3.0", + "autocfg", ] [[package]] @@ -8325,7 +8187,7 @@ dependencies = [ "hmac", "lioness", "log", - "rand 0.8.5", + "rand", "rand_distr", "sha2 0.10.8", "subtle 2.5.0", @@ -8869,7 +8731,7 @@ dependencies = [ "getrandom", "peg", "pin-project", - "rand 0.8.5", + "rand", "reqwest 0.11.27", "semver 1.0.23", "serde", @@ -8923,7 +8785,7 @@ dependencies = [ "nym-pemstore", "nym-validator-client", "nym-vesting-contract-common", - "rand 0.8.5", + "rand", "serde", "serde_json", "sqlx", @@ -9323,7 +9185,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand 0.8.5", + "rand", "slab", "tokio", "tokio-util", @@ -9589,7 +9451,7 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "rand 0.8.5", + "rand", "rustls 0.21.12", "sha1", "thiserror", @@ -9610,7 +9472,7 @@ dependencies = [ "http 1.1.0", "httparse", "log", - "rand 0.8.5", + "rand", "rustls 0.22.4", "rustls-pki-types", "sha1", @@ -10030,7 +9892,7 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand", "serde", "serde-wasm-bindgen 0.6.5", "thiserror", @@ -10665,7 +10527,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-http-api-client", - "rand 0.8.5", + "rand", "reqwest 0.12.4", "serde", "thiserror", diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 51afe221fe9..e2d18d55458 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use crate::utils::{get_coin_index_signatures, get_expiration_date_signatures}; +use crate::utils::{ + get_aggregate_verification_key, get_coin_index_signatures, get_expiration_date_signatures, +}; use log::info; use nym_credential_storage::storage::Storage; use nym_credentials::ecash::bandwidth::IssuanceTicketBook; @@ -55,7 +57,7 @@ where )) } -pub async fn query_and_persist_required_global_signatures( +pub async fn query_and_persist_required_global_data( storage: &S, epoch_id: EpochId, expiration_date: Date, @@ -65,6 +67,10 @@ where S: Storage, ::StorageError: Send + Sync + 'static, { + log::info!("Getting master verification key"); + // this will also persist the key in the storage if was not there already + get_aggregate_verification_key(storage, epoch_id, apis.clone()).await?; + log::info!("Getting expiration date signatures"); // this will also persist the signatures in the storage if they were not there already get_expiration_date_signatures(storage, epoch_id, expiration_date, apis.clone()).await?; diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 4485009b68a..a164d3df60f 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -16,7 +16,7 @@ use nym_credential_storage::models::RetrievedTicketbook; use nym_credential_storage::storage::Storage; use nym_credentials::ecash::bandwidth::CredentialSpendingData; use nym_credentials_interface::{ - AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, NymPayInfo, VerificationKeyAuth, + AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, VerificationKeyAuth, }; use nym_ecash_time::Date; use nym_validator_client::nym_api::EpochId; @@ -165,7 +165,9 @@ impl BandwidthController { .get_coin_index_signatures(epoch_id, &mut api_clients) .await?; - let pay_info = NymPayInfo::generate(provider_pk); + let pay_info = retrieved_ticketbook + .ticketbook + .generate_pay_info(provider_pk); let spend_request = retrieved_ticketbook.ticketbook.prepare_for_spending( &verification_key, diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 2045cf0d2a2..6ff825dcbce 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -7,9 +7,10 @@ license.workspace = true [dependencies] anyhow = { workspace = true } -base64 = "0.13.0" +base64 = { workspace = true } bip39 = { workspace = true } bs58 = { workspace = true } +colored = { workspace = true } comfy-table = { workspace = true } cfg-if = { workspace = true } clap = { workspace = true, features = ["derive"] } @@ -21,13 +22,13 @@ humantime-serde = { workspace = true } inquire = { workspace = true } k256 = { workspace = true, features = ["ecdsa", "sha256"] } log = { workspace = true } -rand = {version = "0.6", features = ["std"] } +rand = { workspace = true, features = ["std"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } time = { workspace = true, features = ["parsing", "formatting"] } -tokio = { workspace = true, features = ["sync"]} -toml = "0.5.6" +tokio = { workspace = true, features = ["sync"] } +toml = { workspace = true } url = { workspace = true } tap = { workspace = true } zeroize = { workspace = true } diff --git a/common/commands/src/ecash/generate_ticket.rs b/common/commands/src/ecash/generate_ticket.rs new file mode 100644 index 00000000000..67a85ab093a --- /dev/null +++ b/common/commands/src/ecash/generate_ticket.rs @@ -0,0 +1,178 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils::CommonConfigsWrapper; +use anyhow::{anyhow, bail}; +use clap::Parser; +use colored::Colorize; +use comfy_table::Table; +use nym_credential_storage::initialise_persistent_storage; +use nym_credential_storage::storage::Storage; +use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise; +use std::path::PathBuf; + +#[derive(Debug, Parser)] +pub struct Args { + /// Specify the index of the ticket to retrieve from the ticketbook. + /// By default, the current unspent value is used. + #[clap(long, group = "output")] + pub(crate) ticket_index: Option, + + /// Specify whether we should display payments for ALL available tickets + #[clap(long, group = "output")] + pub(crate) full: bool, + + /// Base58-encoded identity of the provider (must be 32 bytes long) + #[clap(long)] + pub(crate) provider: String, + + /// Config file of the client that is supposed to use the credential. + #[clap(long, group = "source")] + pub(crate) client_config: Option, + + /// Path to the dedicated credential storage database + #[clap(long, group = "source")] + pub(crate) credential_storage: Option, +} + +pub async fn execute(args: Args) -> anyhow::Result<()> { + let credentials_store = if let Some(explicit) = args.credential_storage { + explicit + } else { + // SAFETY: at least one of them MUST HAVE been specified + let cfg = args.client_config.unwrap(); + + let loaded = CommonConfigsWrapper::try_load(cfg)?; + + if let Ok(id) = loaded.try_get_id() { + println!("loaded config file for client '{id}'"); + } + + let Ok(credentials_store) = loaded.try_get_credentials_store() else { + bail!("the loaded config does not have a credentials store information") + }; + credentials_store + }; + + let decoded_provider = bs58::decode(&args.provider).into_vec()?; + if decoded_provider.len() != 32 { + bail!("the provided provider information is malformed") + } + let provider_arr: [u8; 32] = decoded_provider.try_into().unwrap(); + + let persistent_storage = initialise_persistent_storage(&credentials_store).await; + let Some(mut next_ticketbook) = persistent_storage + .get_next_unspent_usable_ticketbook(0) + .await? + else { + bail!( + "there are no valid ticketbooks in the storage at {}", + credentials_store.display() + ) + }; + + let epoch_id = next_ticketbook.ticketbook.epoch_id(); + let expiration_date = next_ticketbook.ticketbook.expiration_date(); + + let verification_key = persistent_storage + .get_master_verification_key(epoch_id) + .await? + .ok_or_else(|| { + anyhow!("ticketbook got incorrectly imported - the master verification key is missing") + })?; + let expiration_signatures = persistent_storage + .get_expiration_date_signatures(expiration_date) + .await? + .ok_or_else(|| { + anyhow!( + "ticketbook got incorrectly imported - the expiration date signatures are missing" + ) + })?; + let coin_indices_signatures = persistent_storage + .get_coin_index_signatures(epoch_id) + .await? + .ok_or_else(|| { + anyhow!("ticketbook got incorrectly imported - the coin index signatures are missing") + })?; + + let ticketbook_data = next_ticketbook.ticketbook.pack(); + + let next_ticket = args + .ticket_index + .unwrap_or(next_ticketbook.ticketbook.spent_tickets()); + let pay_info = next_ticketbook.ticketbook.generate_pay_info(provider_arr); + + println!("{}", "TICKETBOOK DATA:".bold()); + println!("{}", bs58::encode(&ticketbook_data.data).into_string()); + println!(); + + // display it only for a single ticket + if !args.full { + println!("attempting to generate payment for ticket {next_ticket}..."); + println!(); + next_ticketbook.ticketbook.update_spent_tickets(next_ticket); + + let req = next_ticketbook.ticketbook.prepare_for_spending( + &verification_key, + pay_info.into(), + &coin_indices_signatures, + &expiration_signatures, + 1, + )?; + + let payment = req.payment; + + println!("{}", format!("PAYMENT FOR TICKET {next_ticket}: ").bold()); + println!("{}", bs58::encode(&payment.to_bytes()).into_string()); + return Ok(()); + } + + println!( + "generating payment information for {} tickets. this might take a while!...", + next_ticketbook.ticketbook.params_total_tickets() + ); + + // otherwise generate all the payments + let last_spent = next_ticketbook.ticketbook.spent_tickets(); + + let mut table = Table::new(); + table.set_header(vec!["index", "binary data", "spend status"]); + + for i in 0..next_ticketbook.ticketbook.params_total_tickets() { + let status = if i < last_spent { + "SPENT".red() + } else { + "NOT SPENT".green() + }; + + next_ticketbook.ticketbook.update_spent_tickets(i); + + let req = next_ticketbook.ticketbook.prepare_for_spending( + &verification_key, + pay_info.into(), + &coin_indices_signatures, + &expiration_signatures, + 1, + )?; + + let payment = req.payment; + let payment_bytes = payment.to_bytes(); + let len = payment_bytes.len(); + let display_size = 100; + let remaining = len - display_size; + + table.add_row(vec![ + i.to_string(), + format!( + "{}…{remaining}bytes remaining", + bs58::encode(&payment_bytes[..display_size]).into_string() + ), + status.to_string(), + ]); + } + + println!("{}", "AVAILABLE TICKETS".bold()); + println!("{table}"); + + Ok(()) +} diff --git a/common/commands/src/coconut/import_ticket_book.rs b/common/commands/src/ecash/import_ticket_book.rs similarity index 100% rename from common/commands/src/coconut/import_ticket_book.rs rename to common/commands/src/ecash/import_ticket_book.rs diff --git a/common/commands/src/coconut/issue_ticket_book.rs b/common/commands/src/ecash/issue_ticket_book.rs similarity index 52% rename from common/commands/src/coconut/issue_ticket_book.rs rename to common/commands/src/ecash/issue_ticket_book.rs index c6b0997ba58..eb63f7b322f 100644 --- a/common/commands/src/coconut/issue_ticket_book.rs +++ b/common/commands/src/ecash/issue_ticket_book.rs @@ -9,6 +9,9 @@ use nym_credential_storage::initialise_persistent_storage; use nym_credential_utils::utils; use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::identity; +use rand::rngs::OsRng; +use rand::RngCore; +use std::fs::create_dir_all; use std::path::PathBuf; #[derive(Debug, Parser)] @@ -18,12 +21,20 @@ pub struct Args { pub(crate) ticketbook_type: TicketType, /// Config file of the client that is supposed to use the credential. - #[clap(long)] - pub(crate) client_config: PathBuf, + #[clap(long, group = "output")] + pub(crate) client_config: Option, + + /// Path to the dedicated credential storage database + #[clap(long, group = "output")] + pub(crate) credential_storage: Option, } -pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { - let loaded = CommonConfigsWrapper::try_load(args.client_config)?; +async fn issue_client_ticketbook( + cfg: PathBuf, + typ: TicketType, + client: SigningClient, +) -> anyhow::Result<()> { + let loaded = CommonConfigsWrapper::try_load(cfg)?; if let Ok(id) = loaded.try_get_id() { println!("loaded config file for client '{id}'"); @@ -48,9 +59,40 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { &client, &persistent_storage, &private_id_key.to_bytes(), - args.ticketbook_type, + typ, ) .await?; Ok(()) } + +async fn issue_standalone_ticketbook( + credentials_store: PathBuf, + typ: TicketType, + client: SigningClient, +) -> anyhow::Result<()> { + println!("attempting to issue a standalone ticketbook"); + + let mut rng = OsRng; + let mut random_seed = [0u8; 32]; + rng.fill_bytes(&mut random_seed); + + if let Some(parent) = credentials_store.parent() { + create_dir_all(parent)?; + } + + let persistent_storage = initialise_persistent_storage(credentials_store).await; + utils::issue_credential(&client, &persistent_storage, &random_seed, typ).await?; + + Ok(()) +} + +pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { + match (args.client_config, args.credential_storage) { + (Some(cfg), None) => issue_client_ticketbook(cfg, args.ticketbook_type, client).await, + (None, Some(storage)) => { + issue_standalone_ticketbook(storage, args.ticketbook_type, client).await + } + _ => unreachable!("clap should have made this branch impossible to reach!"), + } +} diff --git a/common/commands/src/coconut/mod.rs b/common/commands/src/ecash/mod.rs similarity index 89% rename from common/commands/src/coconut/mod.rs rename to common/commands/src/ecash/mod.rs index 74421dd42bd..77ca858366b 100644 --- a/common/commands/src/coconut/mod.rs +++ b/common/commands/src/ecash/mod.rs @@ -3,6 +3,7 @@ use clap::{Args, Subcommand}; +pub mod generate_ticket; pub mod import_ticket_book; pub mod issue_ticket_book; pub mod recover_ticket_book; @@ -19,4 +20,5 @@ pub enum EcashCommands { IssueTicketBook(issue_ticket_book::Args), RecoverTicketBook(recover_ticket_book::Args), ImportTicketBook(import_ticket_book::Args), + GenerateTicket(generate_ticket::Args), } diff --git a/common/commands/src/coconut/recover_ticket_book.rs b/common/commands/src/ecash/recover_ticket_book.rs similarity index 100% rename from common/commands/src/coconut/recover_ticket_book.rs rename to common/commands/src/ecash/recover_ticket_book.rs diff --git a/common/commands/src/lib.rs b/common/commands/src/lib.rs index afca2be0f7a..e3670ac5726 100644 --- a/common/commands/src/lib.rs +++ b/common/commands/src/lib.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub mod coconut; pub mod context; +pub mod ecash; pub mod utils; pub mod validator; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs b/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs index 21b026c85ed..fc16a067d20 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs @@ -10,7 +10,11 @@ pub struct Args { } pub fn decode_mixnode_key(args: Args) { - let b64_decoded = base64::decode(args.key).expect("failed to decode base64 string"); + use base64::{engine::general_purpose::STANDARD, Engine as _}; + + let b64_decoded = STANDARD + .decode(args.key) + .expect("failed to decode base64 string"); let b58_encoded = bs58::encode(&b64_decoded).into_string(); println!("{b58_encoded}") diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index 41381d53f99..be7133b4c29 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -3,9 +3,7 @@ use crate::errors::{Error, Result}; use log::*; -use nym_bandwidth_controller::acquire::{ - get_ticket_book, query_and_persist_required_global_signatures, -}; +use nym_bandwidth_controller::acquire::{get_ticket_book, query_and_persist_required_global_data}; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::DEFAULT_DATA_DIR; use nym_credential_storage::persistent_storage::PersistentStorage; @@ -45,14 +43,10 @@ where let apis = all_ecash_api_clients(client, epoch_id).await?; let ticketbook_expiration = ecash_default_expiration_date(); - // make sure we have all required coin indices and expiration date signatures before attempting the deposit - query_and_persist_required_global_signatures( - storage, - epoch_id, - ticketbook_expiration, - apis.clone(), - ) - .await?; + // make sure we have all required coin indices and expiration date signatures alongside the master verification key + // before attempting the deposit + query_and_persist_required_global_data(storage, epoch_id, ticketbook_expiration, apis.clone()) + .await?; let issuance_data = nym_bandwidth_controller::acquire::make_deposit( client, diff --git a/common/credentials/src/ecash/bandwidth/issued.rs b/common/credentials/src/ecash/bandwidth/issued.rs index 8787528ae41..da04d386208 100644 --- a/common/credentials/src/ecash/bandwidth/issued.rs +++ b/common/credentials/src/ecash/bandwidth/issued.rs @@ -6,7 +6,7 @@ use crate::ecash::bandwidth::CredentialSpendingData; use crate::ecash::utils::ecash_today; use crate::error::Error; use nym_credentials_interface::{ - CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, TicketType, + CoinIndexSignature, ExpirationDateSignature, NymPayInfo, PayInfo, SecretKeyUser, TicketType, VerificationKeyAuth, Wallet, WalletSignatures, }; use nym_ecash_time::EcashTime; @@ -114,6 +114,10 @@ impl IssuedTicketBook { &self.signatures_wallet } + pub fn generate_pay_info(&self, provider_pk: [u8; 32]) -> NymPayInfo { + NymPayInfo::generate(provider_pk) + } + pub fn prepare_for_spending( &mut self, verification_key: &VerificationKeyAuth, diff --git a/envs/sandbox.env b/envs/sandbox.env index 6deaafdfaa5..4763269a6f3 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -13,11 +13,10 @@ DENOMS_EXPONENT=6 REWARDING_VALIDATOR_ADDRESS=n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz -ECASH_CONTRACT_ADDRESS=n1ljlwey4xdj0zs7zueepc48nkr033fca6fjgvurfvttqegm8dvsrswsul70 -GROUP_CONTRACT_ADDRESS=n10v3rjnq4cjyccfykyams68ztce337gksuu6f0lvtl4meuwvkewaqru4uav -MULTISIG_CONTRACT_ADDRESS=n1cemnu8as0ls45v3caunpesl8jlsfw2ff9rlwnltlecp7zrxct4dsqc2y42 -COCONUT_DKG_CONTRACT_ADDRESS=n1zx96qgd88vqlzcxkpwzks7kqs5ctrx36xtzfc58p7q6c4ng9anlqzc4nh8 - +GROUP_CONTRACT_ADDRESS=n1ewmwz97xm0h8rdk8sw7h9mwn866qkx9hl9zlmagqfkhuzvwk5hhq844ue9 +MULTISIG_CONTRACT_ADDRESS=n1tz0setr8vkh9udp8xyxgpqc89ns27k4d0jx2h942hr0ax63yjhmqz6xct8 +COCONUT_DKG_CONTRACT_ADDRESS=n1v3n2ly2dp3a9ng3ff6rh26yfkn0pc5hed7w2shc5u9ca5c865utqj5elvh +ECASH_CONTRACT_ADDRESS=n1v3vydvs2ued84yv3khqwtgldmgwn0elljsdh08dr5s2j9x4rc5fs9jlwz9 STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" EXPLORER_API=https://sandbox-explorer.nymtech.net/api diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 19da50eccbf..3f5acbd5e90 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -7,6 +7,7 @@ use nym_credential_utils::utils::issue_credential; use nym_credentials_interface::TicketType; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; +use std::ops::Deref; use zeroize::Zeroizing; /// Represents a client that can be used to acquire bandwidth. You typically create one when you @@ -17,7 +18,7 @@ use zeroize::Zeroizing; pub struct BandwidthAcquireClient<'a, St: Storage> { client: DirectSigningHttpRpcNyxdClient, storage: &'a St, - client_id: Zeroizing, + client_id: Zeroizing>, ticketbook_type: TicketType, } @@ -30,7 +31,7 @@ where network_details: NymNetworkDetails, mnemonic: String, storage: &'a St, - client_id: String, + client_id: Vec, ticketbook_type: TicketType, ) -> Result { let nyxd_url = network_details.endpoints[0].nyxd_url.as_str(); @@ -53,7 +54,7 @@ where issue_credential( &self.client, self.storage, - self.client_id.as_bytes(), + self.client_id.deref(), self.ticketbook_type, ) .await?; diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 7d26b1f9aab..19048f50058 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -40,6 +40,7 @@ use std::net::IpAddr; use std::path::Path; use std::path::PathBuf; use url::Url; +use zeroize::Zeroizing; // The number of surbs to include in a message by default const DEFAULT_NUMBER_OF_SURBS: u32 = 10; @@ -560,17 +561,20 @@ where if !self.config.enabled_credentials_mode { return Err(Error::DisabledCredentialsMode); } - let client_id = self - .storage - .key_store() - .load_keys() - .await - .map_err(|e| Error::KeyStorageError { - source: Box::new(e), - })? - .identity_keypair() - .private_key() - .to_base58_string(); + let client_id_array = Zeroizing::new( + self.storage + .key_store() + .load_keys() + .await + .map_err(|e| Error::KeyStorageError { + source: Box::new(e), + })? + .identity_keypair() + .private_key() + .to_bytes(), + ); + let client_id = client_id_array.to_vec(); + BandwidthAcquireClient::new( self.config.network_details.clone(), mnemonic, diff --git a/tools/nym-cli/src/coconut/mod.rs b/tools/nym-cli/src/coconut/mod.rs deleted file mode 100644 index 6fda72e6a0f..00000000000 --- a/tools/nym-cli/src/coconut/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -use nym_cli_commands::context::{create_query_client, create_signing_client, ClientArgs}; -use nym_network_defaults::NymNetworkDetails; - -pub(crate) async fn execute( - global_args: ClientArgs, - coconut: nym_cli_commands::coconut::Ecash, - network_details: &NymNetworkDetails, -) -> anyhow::Result<()> { - match coconut.command { - nym_cli_commands::coconut::EcashCommands::IssueTicketBook(args) => { - nym_cli_commands::coconut::issue_ticket_book::execute( - args, - create_signing_client(global_args, network_details)?, - ) - .await? - } - nym_cli_commands::coconut::EcashCommands::RecoverTicketBook(args) => { - nym_cli_commands::coconut::recover_ticket_book::execute( - args, - create_query_client(network_details)?, - ) - .await? - } - nym_cli_commands::coconut::EcashCommands::ImportTicketBook(args) => { - nym_cli_commands::coconut::import_ticket_book::execute(args).await? - } - } - Ok(()) -} diff --git a/tools/nym-cli/src/ecash/mod.rs b/tools/nym-cli/src/ecash/mod.rs new file mode 100644 index 00000000000..1cc3d00020a --- /dev/null +++ b/tools/nym-cli/src/ecash/mod.rs @@ -0,0 +1,32 @@ +use nym_cli_commands::context::{create_query_client, create_signing_client, ClientArgs}; +use nym_network_defaults::NymNetworkDetails; + +pub(crate) async fn execute( + global_args: ClientArgs, + coconut: nym_cli_commands::ecash::Ecash, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match coconut.command { + nym_cli_commands::ecash::EcashCommands::IssueTicketBook(args) => { + nym_cli_commands::ecash::issue_ticket_book::execute( + args, + create_signing_client(global_args, network_details)?, + ) + .await? + } + nym_cli_commands::ecash::EcashCommands::RecoverTicketBook(args) => { + nym_cli_commands::ecash::recover_ticket_book::execute( + args, + create_query_client(network_details)?, + ) + .await? + } + nym_cli_commands::ecash::EcashCommands::ImportTicketBook(args) => { + nym_cli_commands::ecash::import_ticket_book::execute(args).await? + } + nym_cli_commands::ecash::EcashCommands::GenerateTicket(args) => { + nym_cli_commands::ecash::generate_ticket::execute(args).await? + } + } + Ok(()) +} diff --git a/tools/nym-cli/src/main.rs b/tools/nym-cli/src/main.rs index 12defe48171..c5b4cc51e31 100644 --- a/tools/nym-cli/src/main.rs +++ b/tools/nym-cli/src/main.rs @@ -7,8 +7,8 @@ use nym_bin_common::logging::setup_logging; use nym_cli_commands::context::{get_network_details, ClientArgs}; use nym_validator_client::nyxd::AccountId; -mod coconut; mod completion; +mod ecash; mod validator; #[derive(Debug, Parser)] @@ -63,7 +63,7 @@ pub(crate) enum Commands { /// Sign and verify messages Signature(nym_cli_commands::validator::signature::Signature), /// Ecash related stuff - Ecash(nym_cli_commands::coconut::Ecash), + Ecash(nym_cli_commands::ecash::Ecash), /// Query chain blocks Block(nym_cli_commands::validator::block::Block), /// Manage and execute WASM smart contracts @@ -104,7 +104,7 @@ async fn execute(cli: Cli) -> anyhow::Result<()> { Commands::Signature(signature) => { validator::signature::execute(signature, &network_details, mnemonic).await? } - Commands::Ecash(coconut) => coconut::execute(args, coconut, &network_details).await?, + Commands::Ecash(coconut) => ecash::execute(args, coconut, &network_details).await?, Commands::Block(block) => validator::block::execute(block, &network_details).await?, Commands::Cosmwasm(cosmwasm) => { validator::cosmwasm::execute(args, cosmwasm, &network_details).await?