Compare commits

..

4 Commits

Author SHA1 Message Date
Jędrzej Stuczyński 2cc99b486e being VERY explicit about loading coconut keys 2023-12-14 10:09:52 +00:00
Jędrzej Stuczyński 556d980c01 fixed node indexing 2023-12-14 09:27:39 +00:00
Jędrzej Stuczyński b86ae7520e hardcoded migration data 2023-12-14 09:05:47 +00:00
Jędrzej Stuczyński 43da0e3aa7 ignore dkg 2023-12-14 08:30:49 +00:00
488 changed files with 9690 additions and 33551 deletions
-21
View File
@@ -1,21 +0,0 @@
name: ci-cargo-deny
on: [workflow_dispatch]
jobs:
cargo-deny:
runs-on: ubuntu-22.04
strategy:
matrix:
checks:
# - advisories
- licenses
- bans sources
continue-on-error: ${{ matrix.checks == 'licenses' }}
steps:
- uses: actions/checkout@v3
- uses: EmbarkStudios/cargo-deny-action@v1
with:
log-level: warn
command: check ${{ matrix.checks }}
argument: --all-features
-3
View File
@@ -17,9 +17,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: install yarn in root
run: cd ../.. yarn install
- name: Install npm - name: Install npm
run: npm install run: npm install
-1
View File
@@ -9,7 +9,6 @@
target target
.env .env
.env.dev .env.dev
envs/devnet.env
/.vscode/settings.json /.vscode/settings.json
validator/.vscode validator/.vscode
sample-configs/validator-config.toml sample-configs/validator-config.toml
Generated
+295 -275
View File
File diff suppressed because it is too large Load Diff
+2 -19
View File
@@ -67,7 +67,6 @@ members = [
"common/nymsphinx/params", "common/nymsphinx/params",
"common/nymsphinx/routing", "common/nymsphinx/routing",
"common/nymsphinx/types", "common/nymsphinx/types",
"common/nyxd-scraper",
"common/pemstore", "common/pemstore",
"common/socks5-client-core", "common/socks5-client-core",
"common/socks5/proxy-helpers", "common/socks5/proxy-helpers",
@@ -102,7 +101,6 @@ members = [
"nym-node", "nym-node",
"nym-node/nym-node-requests", "nym-node/nym-node-requests",
"nym-outfox", "nym-outfox",
"nym-validator-rewarder",
"tools/internal/ssl-inject", "tools/internal/ssl-inject",
"tools/internal/sdk-version-bump", "tools/internal/sdk-version-bump",
"tools/nym-cli", "tools/nym-cli",
@@ -125,7 +123,6 @@ default-members = [
"nym-api", "nym-api",
"tools/nymvisor", "tools/nymvisor",
"explorer-api", "explorer-api",
"nym-validator-rewarder",
] ]
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles"] exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles"]
@@ -162,12 +159,10 @@ reqwest = "0.11.22"
schemars = "0.8.1" schemars = "0.8.1"
serde = "1.0.152" serde = "1.0.152"
serde_json = "1.0.91" serde_json = "1.0.91"
sqlx = "0.6.3"
tap = "1.0.1" tap = "1.0.1"
time = "0.3.30" time = "0.3.30"
thiserror = "1.0.48" thiserror = "1.0.48"
tokio = "1.33.0" tokio = "1.24.1"
tokio-util = "0.7.10"
tokio-tungstenite = "0.20.1" tokio-tungstenite = "0.20.1"
tracing = "0.1.37" tracing = "0.1.37"
tungstenite = { version = "0.20.1", default-features = false } tungstenite = { version = "0.20.1", default-features = false }
@@ -177,14 +172,6 @@ utoipa-swagger-ui = "3.1.5"
url = "2.4" url = "2.4"
zeroize = "1.6.0" zeroize = "1.6.0"
# coconut/DKG related
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="feature/gt-serialization-0.8.0" }
group = "0.13.0"
ff = "0.13.0"
# cosmwasm-related # cosmwasm-related
cosmwasm-derive = "=1.3.0" cosmwasm-derive = "=1.3.0"
cosmwasm-schema = "=1.3.0" cosmwasm-schema = "=1.3.0"
@@ -203,11 +190,7 @@ cw-controllers = { version = "=1.1.0" }
# cosmrs-related # cosmrs-related
bip32 = "0.5.1" bip32 = "0.5.1"
cosmrs = "=0.15.0"
# temporarily using a fork again (yay.) because we need staking and slashing support
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" }
#cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support
tendermint = "0.34" # same version as used by cosmrs
tendermint-rpc = "0.34" # same version as used by cosmrs tendermint-rpc = "0.34" # same version as used by cosmrs
prost = "0.12" prost = "0.12"
-70
View File
@@ -1,70 +0,0 @@
<html>
<head>
<style>
@media (prefers-color-scheme: dark) {
body {
background: #333;
color: white;
}
a {
color: skyblue;
}
}
.container {
font-family: sans-serif;
max-width: 800px;
margin: 0 auto;
}
.intro {
text-align: center;
}
.licenses-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.license-used-by {
margin-top: -10px;
}
.license-text {
max-height: 200px;
overflow-y: scroll;
white-space: pre-wrap;
}
</style>
</head>
<body>
<main class="container">
<div class="intro">
<h1>Third Party Licenses</h1>
<p>This page lists the licenses of the projects used in cargo-about.</p>
</div>
<h2>Overview of licenses:</h2>
<ul class="licenses-overview">
{{#each overview}}
<li><a href="#{{id}}">{{name}}</a> ({{count}})</li>
{{/each}}
</ul>
<h2>All license text:</h2>
<ul class="licenses-list">
{{#each licenses}}
<li class="license">
<h3 id="{{id}}">{{name}}</h3>
<h4>Used by:</h4>
<ul class="license-used-by">
{{#each used_by}}
<li><a href="{{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}}">{{crate.name}} {{crate.version}}</a></li>
{{/each}}
</ul>
<pre class="license-text">{{text}}</pre>
</li>
{{/each}}
</ul>
</main>
</body>
</html>
-19
View File
@@ -1,19 +0,0 @@
private = { ignore = true }
accepted = [
"0BSD",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"CC0-1.0",
"ISC",
"MIT",
"MPL-2.0",
"Unicode-DFS-2016",
"OpenSSL",
]
workarounds = [
"ring",
"rustls",
]
-1
View File
@@ -5,7 +5,6 @@ authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej St
description = "Implementation of the Nym Client" description = "Implementation of the Nym Client"
edition = "2021" edition = "2021"
rust-version = "1.65" rust-version = "1.65"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -1667,9 +1667,9 @@
} }
}, },
"node_modules/follow-redirects": { "node_modules/follow-redirects": {
"version": "1.15.4", "version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -5800,9 +5800,9 @@
} }
}, },
"follow-redirects": { "follow-redirects": {
"version": "1.15.4", "version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"dev": true "dev": true
}, },
"forwarded": { "forwarded": {
@@ -3,7 +3,6 @@ name = "nym-client-websocket-requests"
version = "0.1.0" version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-1
View File
@@ -5,7 +5,6 @@ authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021" edition = "2021"
rust-version = "1.56" rust-version = "1.56"
license.workspace = true
[dependencies] [dependencies]
clap = { workspace = true, features = ["cargo", "derive"] } clap = { workspace = true, features = ["cargo", "derive"] }
-4
View File
@@ -1,4 +0,0 @@
module.exports = {
ConfigHandler: require('./config/configHandler.ts'),
RestClient: require('./restClient/RestClient.ts')
};
-1
View File
@@ -2,7 +2,6 @@
name = "async-file-watcher" name = "async-file-watcher"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-2
View File
@@ -2,7 +2,6 @@
name = "nym-bandwidth-controller" name = "nym-bandwidth-controller"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,7 +10,6 @@ bip39 = { workspace = true }
rand = "0.7.3" rand = "0.7.3"
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true } url = { workspace = true }
zeroize = { workspace = true }
nym-coconut-interface = { path = "../coconut-interface" } nym-coconut-interface = { path = "../coconut-interface" }
nym-credential-storage = { path = "../credential-storage" } nym-credential-storage = { path = "../credential-storage" }
+15 -12
View File
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::error::BandwidthControllerError; use crate::error::BandwidthControllerError;
use nym_coconut_interface::Base58; use nym_coconut_interface::{Base58, Parameters};
use nym_credential_storage::storage::Storage; use nym_credential_storage::storage::Storage;
use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_credentials::coconut::utils::obtain_aggregate_signature;
use nym_crypto::asymmetric::{encryption, identity}; use nym_crypto::asymmetric::{encryption, identity};
use nym_network_defaults::VOUCHER_INFO; use nym_network_defaults::VOUCHER_INFO;
@@ -12,8 +12,10 @@ use nym_validator_client::coconut::all_coconut_api_clients;
use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
use nym_validator_client::nyxd::Coin; use nym_validator_client::nyxd::Coin;
use nym_validator_client::nyxd::Hash;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use state::State; use state::{KeyPair, State};
use std::str::FromStr;
pub mod state; pub mod state;
@@ -22,29 +24,30 @@ where
C: CoconutBandwidthSigningClient + Sync, C: CoconutBandwidthSigningClient + Sync,
{ {
let mut rng = OsRng; let mut rng = OsRng;
let signing_key = identity::PrivateKey::new(&mut rng); let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng));
let encryption_key = encryption::PrivateKey::new(&mut rng); let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng));
let params = BandwidthVoucher::default_parameters(); let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let voucher_value = amount.amount.to_string(); let voucher_value = amount.amount.to_string();
let tx_hash = client let tx_hash = client
.deposit( .deposit(
amount, amount,
String::from(VOUCHER_INFO), String::from(VOUCHER_INFO),
signing_key.public_key().to_base58_string(), signing_keypair.public_key.clone(),
encryption_key.public_key().to_base58_string(), encryption_keypair.public_key.clone(),
None, None,
) )
.await? .await?
.transaction_hash; .transaction_hash
.to_string();
let voucher = BandwidthVoucher::new( let voucher = BandwidthVoucher::new(
&params, &params,
voucher_value, voucher_value,
VOUCHER_INFO.to_string(), VOUCHER_INFO.to_string(),
tx_hash, Hash::from_str(&tx_hash).map_err(|_| BandwidthControllerError::InvalidTxHash)?,
signing_key, identity::PrivateKey::from_base58_string(&signing_keypair.private_key)?,
encryption_key, encryption::PrivateKey::from_base58_string(&encryption_keypair.private_key)?,
); );
let state = State { voucher, params }; let state = State { voucher, params };
@@ -2,7 +2,32 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use nym_coconut_interface::Parameters; use nym_coconut_interface::Parameters;
use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use nym_crypto::asymmetric::{encryption, identity};
pub(crate) struct KeyPair {
pub public_key: String,
pub private_key: String,
}
impl From<identity::KeyPair> for KeyPair {
fn from(kp: identity::KeyPair) -> Self {
Self {
public_key: kp.public_key().to_base58_string(),
private_key: kp.private_key().to_base58_string(),
}
}
}
impl From<encryption::KeyPair> for KeyPair {
fn from(kp: encryption::KeyPair) -> Self {
Self {
public_key: kp.public_key().to_base58_string(),
private_key: kp.private_key().to_base58_string(),
}
}
}
pub struct State { pub struct State {
pub voucher: BandwidthVoucher, pub voucher: BandwidthVoucher,
@@ -13,7 +38,7 @@ impl State {
pub fn new(voucher: BandwidthVoucher) -> Self { pub fn new(voucher: BandwidthVoucher) -> Self {
State { State {
voucher, voucher,
params: BandwidthVoucher::default_parameters(), params: Parameters::new(TOTAL_ATTRIBUTES).unwrap(),
} }
} }
} }
+6 -9
View File
@@ -7,7 +7,6 @@ use nym_credential_storage::storage::Storage;
use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::coconut::all_coconut_api_clients;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
use std::str::FromStr; use std::str::FromStr;
use zeroize::Zeroizing;
use { use {
nym_coconut_interface::Base58, nym_coconut_interface::Base58,
nym_credentials::coconut::{ nym_credentials::coconut::{
@@ -47,12 +46,10 @@ impl<C, St: Storage> BandwidthController<C, St> {
let voucher_value = u64::from_str(&bandwidth_credential.voucher_value) let voucher_value = u64::from_str(&bandwidth_credential.voucher_value)
.map_err(|_| StorageError::InconsistentData)?; .map_err(|_| StorageError::InconsistentData)?;
let voucher_info = bandwidth_credential.voucher_info.clone(); let voucher_info = bandwidth_credential.voucher_info.clone();
let serial_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( let serial_number =
bandwidth_credential.serial_number, nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.serial_number)?;
)?); let binding_number =
let binding_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.binding_number)?;
bandwidth_credential.binding_number,
)?);
let signature = let signature =
nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?; nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?;
let epoch_id = u64::from_str(&bandwidth_credential.epoch_id) let epoch_id = u64::from_str(&bandwidth_credential.epoch_id)
@@ -67,8 +64,8 @@ impl<C, St: Storage> BandwidthController<C, St> {
prepare_for_spending( prepare_for_spending(
voucher_value, voucher_value,
voucher_info, voucher_info,
&serial_number, serial_number,
&binding_number, binding_number,
epoch_id, epoch_id,
&signature, &signature,
&verification_key, &verification_key,
+1 -2
View File
@@ -35,10 +35,9 @@ opentelemetry = { version = "0.19.0", optional = true, features = ["rt-tokio"] }
[build-dependencies] [build-dependencies]
vergen = { version = "=8.2.6", default-features = false, features = [ vergen = { version = "=7.4.3", default-features = false, features = [
"build", "build",
"git", "git",
"gitcl",
"rustc", "rustc",
"cargo", "cargo",
] } ] }
+7 -8
View File
@@ -1,14 +1,13 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use vergen::EmitBuilder; use vergen::{vergen, Config};
fn main() { fn main() {
EmitBuilder::builder() let mut config = Config::default();
.all_build() if std::env::var("DOCS_RS").is_ok() {
.all_git() // If we don't have access to git information, such as in a docs.rs build, don't error
.all_rustc() *config.git_mut().skip_if_error_mut() = true;
.all_cargo() }
.emit() vergen(config).expect("failed to extract build metadata");
.expect("failed to extract build metadata");
} }
+10 -10
View File
@@ -40,9 +40,9 @@ pub struct BinaryBuildInformation {
/// Provides the rustc channel that was used for the build, for example `nightly`. /// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: &'static str, pub rustc_channel: &'static str,
// VERGEN_CARGO_DEBUG // VERGEN_CARGO_PROFILE
/// Provides the cargo debug mode that was used for the build. /// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_debug: &'static str, pub cargo_profile: &'static str,
} }
impl BinaryBuildInformation { impl BinaryBuildInformation {
@@ -57,7 +57,7 @@ impl BinaryBuildInformation {
commit_branch: env!("VERGEN_GIT_BRANCH"), commit_branch: env!("VERGEN_GIT_BRANCH"),
rustc_version: env!("VERGEN_RUSTC_SEMVER"), rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"), rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_debug: env!("VERGEN_CARGO_DEBUG"), cargo_profile: env!("VERGEN_CARGO_PROFILE"),
} }
} }
@@ -71,7 +71,7 @@ impl BinaryBuildInformation {
commit_branch: self.commit_branch.to_owned(), commit_branch: self.commit_branch.to_owned(),
rustc_version: self.rustc_version.to_owned(), rustc_version: self.rustc_version.to_owned(),
rustc_channel: self.rustc_channel.to_owned(), rustc_channel: self.rustc_channel.to_owned(),
cargo_debug: self.cargo_debug.to_owned(), cargo_profile: self.cargo_profile.to_owned(),
} }
} }
@@ -115,9 +115,9 @@ pub struct BinaryBuildInformationOwned {
/// Provides the rustc channel that was used for the build, for example `nightly`. /// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: String, pub rustc_channel: String,
// VERGEN_CARGO_DEBUG // VERGEN_CARGO_PROFILE
/// Provides the cargo debug mode that was used for the build. /// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_debug: String, pub cargo_profile: String,
} }
impl Display for BinaryBuildInformationOwned { impl Display for BinaryBuildInformationOwned {
@@ -151,8 +151,8 @@ impl Display for BinaryBuildInformationOwned {
self.rustc_version, self.rustc_version,
"rustc Channel:", "rustc Channel:",
self.rustc_channel, self.rustc_channel,
"cargo Debug:", "cargo Profile:",
self.cargo_debug, self.cargo_profile,
) )
} }
} }
+2 -3
View File
@@ -4,7 +4,6 @@ version = "1.1.15"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"] authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021" edition = "2021"
rust-version = "1.66" rust-version = "1.66"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -59,7 +58,7 @@ features = ["time"]
version = "0.20.1" version = "0.20.1"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true version = "0.6.2"
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
optional = true optional = true
@@ -90,7 +89,7 @@ tempfile = "3.1.0"
[build-dependencies] [build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
[features] [features]
default = [] default = []
@@ -1,8 +1,6 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#![allow(unused_imports)]
use std::time::Duration; use std::time::Duration;
pub use wasmtimer::{std::Instant, tokio::*}; pub use wasmtimer::{std::Instant, tokio::*};
@@ -127,9 +127,7 @@ impl ActionController {
.insert(frag_id, (Arc::new(pending_ack), None)) .insert(frag_id, (Arc::new(pending_ack), None))
.is_some() .is_some()
{ {
// This used to be a panic, however since we've seen this actually happen in the panic!("Tried to insert duplicate pending ack")
// wild, let's not take the whole client (and possibly gateway) down because of it.
error!("Tried to insert duplicate pending ack! This should not be possible!")
} }
} }
} }
@@ -3,7 +3,6 @@ name = "nym-gateway-client"
version = "0.1.0" version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+2 -3
View File
@@ -3,15 +3,14 @@ name = "nym-mixnet-client"
version = "0.1.0" version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"] authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
futures = { workspace = true } futures = { workspace = true }
log = { workspace = true } log = { workspace = true }
tokio = { workspace = true, features = ["time", "net", "rt"] } tokio = { version = "1.24.1", features = ["time", "net", "rt"] }
tokio-util = { workspace = true, features = ["codec"] } tokio-util = { version = "0.7.4", features = ["codec"] }
# internal # internal
nym-sphinx = { path = "../../nymsphinx" } nym-sphinx = { path = "../../nymsphinx" }
@@ -4,7 +4,6 @@ version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
rust-version = "1.56" rust-version = "1.56"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -42,14 +42,6 @@ pub struct Config {
nyxd_config: nyxd::Config, nyxd_config: nyxd::Config,
} }
impl TryFrom<NymNetworkDetails> for Config {
type Error = ValidatorClientError;
fn try_from(value: NymNetworkDetails) -> Result<Self, Self::Error> {
Config::try_from_nym_network_details(&value)
}
}
impl Config { impl Config {
pub fn try_from_nym_network_details( pub fn try_from_nym_network_details(
details: &NymNetworkDetails, details: &NymNetworkDetails,
@@ -5,24 +5,16 @@ use crate::nym_api::error::NymAPIError;
use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG}; use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG};
use async_trait::async_trait; use async_trait::async_trait;
use http_api_client::{ApiClient, NO_PARAMS}; use http_api_client::{ApiClient, NO_PARAMS};
pub use nym_api_requests::{ use nym_api_requests::coconut::{
coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
models::{ };
EpochCredentialsResponse, IssuedCredential, IssuedCredentialBody, use nym_api_requests::models::{
IssuedCredentialResponse, IssuedCredentialsResponse, ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse,
}, GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse,
BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse,
VerifyCredentialBody, VerifyCredentialResponse, MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse,
}, StakeSaturationResponse, UptimeResponse,
models::{
ComputeRewardEstParam, DescribedGateway, GatewayBondAnnotated, GatewayCoreStatusResponse,
GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse,
MixNodeBondAnnotated, MixnodeCoreStatusResponse, MixnodeStatusReportResponse,
MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse,
StakeSaturationResponse, UptimeResponse,
},
}; };
pub use nym_coconut_dkg_common::types::EpochId;
use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId}; use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use nym_name_service_common::response::NamesListResponse; use nym_name_service_common::response::NamesListResponse;
@@ -407,60 +399,6 @@ pub trait NymApiClientExt: ApiClient {
.await .await
} }
async fn epoch_credentials(
&self,
dkg_epoch: EpochId,
) -> Result<EpochCredentialsResponse, NymAPIError> {
self.get_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_EPOCH_CREDENTIALS,
&dkg_epoch.to_string(),
],
NO_PARAMS,
)
.await
}
async fn issued_credential(
&self,
credential_id: i64,
) -> Result<IssuedCredentialResponse, NymAPIError> {
self.get_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_ISSUED_CREDENTIAL,
&credential_id.to_string(),
],
NO_PARAMS,
)
.await
}
async fn issued_credentials(
&self,
credential_ids: Vec<i64>,
) -> Result<IssuedCredentialsResponse, NymAPIError> {
self.post_json(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_ISSUED_CREDENTIALS,
],
NO_PARAMS,
&CredentialsRequestBody {
credential_ids,
pagination: None,
},
)
.await
}
async fn get_service_providers(&self) -> Result<ServicesListResponse, NymAPIError> { async fn get_service_providers(&self) -> Result<ServicesListResponse, NymAPIError> {
log::trace!("Getting service providers"); log::trace!("Getting service providers");
self.get_json(&[routes::API_VERSION, routes::SERVICE_PROVIDERS], NO_PARAMS) self.get_json(&[routes::API_VERSION, routes::SERVICE_PROVIDERS], NO_PARAMS)
@@ -17,9 +17,6 @@ pub const BANDWIDTH: &str = "bandwidth";
pub const COCONUT_BLIND_SIGN: &str = "blind-sign"; pub const COCONUT_BLIND_SIGN: &str = "blind-sign";
pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential"; pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential";
pub const COCONUT_EPOCH_CREDENTIALS: &str = "epoch-credentials";
pub const COCONUT_ISSUED_CREDENTIAL: &str = "issued-credential";
pub const COCONUT_ISSUED_CREDENTIALS: &str = "issued-credentials";
pub const STATUS_ROUTES: &str = "status"; pub const STATUS_ROUTES: &str = "status";
pub const MIXNODE: &str = "mixnode"; pub const MIXNODE: &str = "mixnode";
@@ -8,8 +8,6 @@ use cosmwasm_std::{Fraction, Uint128};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::ops::Div; use std::ops::Div;
use std::str::FromStr;
use thiserror::Error;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq)] #[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq)]
pub struct MismatchedDenoms; pub struct MismatchedDenoms;
@@ -128,37 +126,6 @@ impl From<CosmWasmCoin> for Coin {
} }
} }
// unfortunately cosmwasm didn't re-export this correct so we just redefine its
#[derive(Error, Debug, PartialEq, Eq)]
pub enum CoinFromStrError {
#[error("Missing denominator")]
MissingDenom,
#[error("Missing amount or non-digit characters in amount")]
MissingAmount,
#[error("Invalid amount: {0}")]
InvalidAmount(#[from] std::num::ParseIntError),
}
impl FromStr for Coin {
type Err = CoinFromStrError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let pos = s
.find(|c: char| !c.is_ascii_digit())
.ok_or(CoinFromStrError::MissingDenom)?;
let (amount, denom) = s.split_at(pos);
if amount.is_empty() {
return Err(CoinFromStrError::MissingAmount);
}
Ok(Coin {
amount: amount.parse::<u128>()?,
denom: denom.to_string(),
})
}
}
pub trait CoinConverter { pub trait CoinConverter {
type Target; type Target;
@@ -32,7 +32,7 @@ pub trait CoconutBandwidthSigningClient {
fee: Option<Fee>, fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> { ) -> Result<ExecuteResult, NyxdError> {
let req = CoconutBandwidthExecuteMsg::DepositFunds { let req = CoconutBandwidthExecuteMsg::DepositFunds {
data: DepositData::new(info, verification_key, encryption_key), data: DepositData::new(info.to_string(), verification_key, encryption_key),
}; };
self.execute_coconut_bandwidth_contract( self.execute_coconut_bandwidth_contract(
fee, fee,
@@ -1,4 +1,4 @@
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::collect_paged; use crate::collect_paged;
@@ -7,21 +7,13 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient; use crate::nyxd::CosmWasmClient;
use async_trait::async_trait; use async_trait::async_trait;
use cosmrs::AccountId; use cosmrs::AccountId;
use nym_coconut_dkg_common::types::ChunkIndex; use nym_coconut_dkg_common::dealer::{
use serde::Deserialize; ContractDealing, DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse,
pub use nym_coconut_dkg_common::{
dealer::{DealerDetailsResponse, PagedDealerResponse},
dealing::{
DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse,
DealingMetadataResponse, DealingStatusResponse,
},
msg::QueryMsg as DkgQueryMsg,
types::{
DealerDetails, DealingIndex, Epoch, EpochId, EpochState, InitialReplacementData, State,
},
verification_key::{ContractVKShare, PagedVKSharesResponse, VkShareResponse},
}; };
use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg;
use nym_coconut_dkg_common::types::{DealerDetails, Epoch, EpochId, InitialReplacementData};
use nym_coconut_dkg_common::verification_key::{ContractVKShare, PagedVKSharesResponse};
use serde::Deserialize;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
@@ -30,16 +22,10 @@ pub trait DkgQueryClient {
where where
for<'a> T: Deserialize<'a>; for<'a> T: Deserialize<'a>;
async fn get_state(&self) -> Result<State, NyxdError> {
let request = DkgQueryMsg::GetState {};
self.query_dkg_contract(request).await
}
async fn get_current_epoch(&self) -> Result<Epoch, NyxdError> { async fn get_current_epoch(&self) -> Result<Epoch, NyxdError> {
let request = DkgQueryMsg::GetCurrentEpochState {}; let request = DkgQueryMsg::GetCurrentEpochState {};
self.query_dkg_contract(request).await self.query_dkg_contract(request).await
} }
async fn get_current_epoch_threshold(&self) -> Result<Option<u64>, NyxdError> { async fn get_current_epoch_threshold(&self) -> Result<Option<u64>, NyxdError> {
let request = DkgQueryMsg::GetCurrentEpochThreshold {}; let request = DkgQueryMsg::GetCurrentEpochThreshold {};
self.query_dkg_contract(request).await self.query_dkg_contract(request).await
@@ -78,86 +64,17 @@ pub trait DkgQueryClient {
self.query_dkg_contract(request).await self.query_dkg_contract(request).await
} }
async fn get_dealings_metadata( async fn get_dealings_paged(
&self, &self,
epoch_id: EpochId, idx: u64,
dealer: String, start_after: Option<String>,
dealing_index: DealingIndex, limit: Option<u32>,
) -> Result<DealingMetadataResponse, NyxdError> { ) -> Result<PagedDealingsResponse, NyxdError> {
let request = DkgQueryMsg::GetDealingsMetadata { let request = DkgQueryMsg::GetDealing {
epoch_id, idx,
dealer, limit,
dealing_index, start_after,
}; };
self.query_dkg_contract(request).await
}
async fn get_dealer_dealings_status(
&self,
epoch_id: EpochId,
dealer: String,
) -> Result<DealerDealingsStatusResponse, NyxdError> {
let request = DkgQueryMsg::GetDealerDealingsStatus { epoch_id, dealer };
self.query_dkg_contract(request).await
}
async fn get_dealing_status(
&self,
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
) -> Result<DealingStatusResponse, NyxdError> {
let request = DkgQueryMsg::GetDealingStatus {
epoch_id,
dealer,
dealing_index,
};
self.query_dkg_contract(request).await
}
async fn get_dealing_chunk_status(
&self,
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
chunk_index: ChunkIndex,
) -> Result<DealingChunkStatusResponse, NyxdError> {
let request = DkgQueryMsg::GetDealingChunkStatus {
epoch_id,
dealer,
dealing_index,
chunk_index,
};
self.query_dkg_contract(request).await
}
async fn get_dealing_chunk(
&self,
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
chunk_index: ChunkIndex,
) -> Result<DealingChunkResponse, NyxdError> {
let request = DkgQueryMsg::GetDealingChunk {
epoch_id,
dealer,
dealing_index,
chunk_index,
};
self.query_dkg_contract(request).await
}
async fn get_vk_share(
&self,
epoch_id: EpochId,
owner: String,
) -> Result<VkShareResponse, NyxdError> {
let request = DkgQueryMsg::GetVerificationKey { epoch_id, owner };
self.query_dkg_contract(request).await self.query_dkg_contract(request).await
} }
@@ -174,11 +91,6 @@ pub trait DkgQueryClient {
}; };
self.query_dkg_contract(request).await self.query_dkg_contract(request).await
} }
async fn get_contract_cw2_version(&self) -> Result<cw2::ContractVersion, NyxdError> {
self.query_dkg_contract(DkgQueryMsg::GetCW2ContractVersion {})
.await
}
} }
// extension trait to the query client to deal with the paged queries // extension trait to the query client to deal with the paged queries
@@ -194,6 +106,10 @@ pub trait PagedDkgQueryClient: DkgQueryClient {
collect_paged!(self, get_past_dealers_paged, dealers) collect_paged!(self, get_past_dealers_paged, dealers)
} }
async fn get_all_epoch_dealings(&self, idx: u64) -> Result<Vec<ContractDealing>, NyxdError> {
collect_paged!(self, get_dealings_paged, dealings, idx)
}
async fn get_all_verification_key_shares( async fn get_all_verification_key_shares(
&self, &self,
epoch_id: EpochId, epoch_id: EpochId,
@@ -227,7 +143,6 @@ where
mod tests { mod tests {
use super::*; use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue; use crate::nyxd::contract_traits::tests::IgnoreValue;
use nym_coconut_dkg_common::msg::QueryMsg;
// it's enough that this compiles and clippy is happy about it // it's enough that this compiles and clippy is happy about it
#[allow(dead_code)] #[allow(dead_code)]
@@ -236,7 +151,6 @@ mod tests {
msg: DkgQueryMsg, msg: DkgQueryMsg,
) { ) {
match msg { match msg {
DkgQueryMsg::GetState {} => client.get_state().ignore(),
DkgQueryMsg::GetCurrentEpochState {} => client.get_current_epoch().ignore(), DkgQueryMsg::GetCurrentEpochState {} => client.get_current_epoch().ignore(),
DkgQueryMsg::GetCurrentEpochThreshold {} => { DkgQueryMsg::GetCurrentEpochThreshold {} => {
client.get_current_epoch_threshold().ignore() client.get_current_epoch_threshold().ignore()
@@ -251,42 +165,11 @@ mod tests {
DkgQueryMsg::GetPastDealers { limit, start_after } => { DkgQueryMsg::GetPastDealers { limit, start_after } => {
client.get_past_dealers_paged(start_after, limit).ignore() client.get_past_dealers_paged(start_after, limit).ignore()
} }
DkgQueryMsg::GetDealingStatus { DkgQueryMsg::GetDealing {
epoch_id, idx,
dealer, limit,
dealing_index, start_after,
} => client } => client.get_dealings_paged(idx, start_after, limit).ignore(),
.get_dealing_status(epoch_id, dealer, dealing_index)
.ignore(),
DkgQueryMsg::GetDealingsMetadata {
epoch_id,
dealer,
dealing_index,
} => client
.get_dealings_metadata(epoch_id, dealer, dealing_index)
.ignore(),
QueryMsg::GetDealerDealingsStatus { epoch_id, dealer } => {
client.get_dealer_dealings_status(epoch_id, dealer).ignore()
}
DkgQueryMsg::GetDealingChunkStatus {
epoch_id,
dealer,
dealing_index,
chunk_index,
} => client
.get_dealing_chunk_status(epoch_id, dealer, dealing_index, chunk_index)
.ignore(),
DkgQueryMsg::GetDealingChunk {
epoch_id,
dealer,
dealing_index,
chunk_index,
} => client
.get_dealing_chunk(epoch_id, dealer, dealing_index, chunk_index)
.ignore(),
DkgQueryMsg::GetVerificationKey { epoch_id, owner } => {
client.get_vk_share(epoch_id, owner).ignore()
}
DkgQueryMsg::GetVerificationKeys { DkgQueryMsg::GetVerificationKeys {
epoch_id, epoch_id,
limit, limit,
@@ -294,7 +177,6 @@ mod tests {
} => client } => client
.get_vk_shares_paged(epoch_id, start_after, limit) .get_vk_shares_paged(epoch_id, start_after, limit)
.ignore(), .ignore(),
DkgQueryMsg::GetCW2ContractVersion {} => client.get_contract_cw2_version().ignore(),
}; };
} }
} }
@@ -8,11 +8,11 @@ use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
use crate::signing::signer::OfflineSigner; use crate::signing::signer::OfflineSigner;
use async_trait::async_trait; use async_trait::async_trait;
use cosmrs::AccountId; use cosmrs::AccountId;
use nym_coconut_dkg_common::dealing::{DealingChunkInfo, PartialContractDealing}; use cosmwasm_std::Addr;
use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg; use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg;
use nym_coconut_dkg_common::types::{DealingIndex, EncodedBTEPublicKeyWithProof}; use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof;
use nym_coconut_dkg_common::verification_key::VerificationKeyShare; use nym_coconut_dkg_common::verification_key::VerificationKeyShare;
use nym_contracts_common::IdentityKey; use nym_contracts_common::dealings::ContractSafeBytes;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
@@ -25,13 +25,6 @@ pub trait DkgSigningClient {
funds: Vec<Coin>, funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>; ) -> Result<ExecuteResult, NyxdError>;
async fn initiate_dkg(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::InitiateDkg {};
self.execute_dkg_contract(fee, req, "initiating the DKG".to_string(), vec![])
.await
}
async fn advance_dkg_epoch_state(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> { async fn advance_dkg_epoch_state(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::AdvanceEpochState {}; let req = DkgExecuteMsg::AdvanceEpochState {};
@@ -49,14 +42,12 @@ pub trait DkgSigningClient {
async fn register_dealer( async fn register_dealer(
&self, &self,
bte_key: EncodedBTEPublicKeyWithProof, bte_key: EncodedBTEPublicKeyWithProof,
identity_key: IdentityKey,
announce_address: String, announce_address: String,
resharing: bool, resharing: bool,
fee: Option<Fee>, fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> { ) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::RegisterDealer { let req = DkgExecuteMsg::RegisterDealer {
bte_key_with_proof: bte_key, bte_key_with_proof: bte_key,
identity_key,
announce_address, announce_address,
resharing, resharing,
}; };
@@ -65,32 +56,18 @@ pub trait DkgSigningClient {
.await .await
} }
async fn submit_dealing_metadata( async fn submit_dealing_bytes(
&self, &self,
dealing_index: DealingIndex, dealing_bytes: ContractSafeBytes,
chunks: Vec<DealingChunkInfo>,
resharing: bool, resharing: bool,
fee: Option<Fee>, fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> { ) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::CommitDealingsMetadata { let req = DkgExecuteMsg::CommitDealing {
dealing_index, dealing_bytes,
chunks,
resharing, resharing,
}; };
self.execute_dkg_contract(fee, req, "dealing metadata commitment".to_string(), vec![]) self.execute_dkg_contract(fee, req, "dealing commitment".to_string(), vec![])
.await
}
async fn submit_dealing_chunk(
&self,
chunk: PartialContractDealing,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::CommitDealingsChunk { chunk, resharing };
self.execute_dkg_contract(fee, req, "dealing chunk commitment".to_string(), vec![])
.await .await
} }
@@ -117,10 +94,9 @@ pub trait DkgSigningClient {
resharing: bool, resharing: bool,
fee: Option<Fee>, fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> { ) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::VerifyVerificationKeyShare { // the call to unchecked is fine as we're converting from pre-validated `AccountId`
owner: owner.to_string(), let owner = Addr::unchecked(owner.to_string());
resharing, let req = DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing };
};
self.execute_dkg_contract( self.execute_dkg_contract(
fee, fee,
@@ -170,36 +146,28 @@ mod tests {
msg: DkgExecuteMsg, msg: DkgExecuteMsg,
) { ) {
match msg { match msg {
DkgExecuteMsg::InitiateDkg {} => client.initiate_dkg(None).ignore(),
DkgExecuteMsg::RegisterDealer { DkgExecuteMsg::RegisterDealer {
bte_key_with_proof, bte_key_with_proof,
identity_key,
announce_address, announce_address,
resharing, resharing,
} => client } => client
.register_dealer( .register_dealer(bte_key_with_proof, announce_address, resharing, None)
bte_key_with_proof,
identity_key,
announce_address,
resharing,
None,
)
.ignore(), .ignore(),
DkgExecuteMsg::CommitDealingsMetadata { DkgExecuteMsg::CommitDealing {
dealing_index, dealing_bytes,
chunks,
resharing, resharing,
} => client } => client
.submit_dealing_metadata(dealing_index, chunks, resharing, None) .submit_dealing_bytes(dealing_bytes, resharing, None)
.ignore(), .ignore(),
DkgExecuteMsg::CommitDealingsChunk { chunk, resharing } => {
client.submit_dealing_chunk(chunk, resharing, None).ignore()
}
DkgExecuteMsg::CommitVerificationKeyShare { share, resharing } => client DkgExecuteMsg::CommitVerificationKeyShare { share, resharing } => client
.submit_verification_key_share(share, resharing, None) .submit_verification_key_share(share, resharing, None)
.ignore(), .ignore(),
DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => client DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => client
.verify_verification_key_share(&owner.parse().unwrap(), resharing, None) .verify_verification_key_share(
&owner.into_string().parse().unwrap(),
resharing,
None,
)
.ignore(), .ignore(),
DkgExecuteMsg::SurpassedThreshold {} => client.surpass_threshold(None).ignore(), DkgExecuteMsg::SurpassedThreshold {} => client.surpass_threshold(None).ignore(),
DkgExecuteMsg::AdvanceEpochState {} => client.advance_dkg_epoch_state(None).ignore(), DkgExecuteMsg::AdvanceEpochState {} => client.advance_dkg_epoch_state(None).ignore(),
@@ -8,26 +8,26 @@ use std::str::FromStr;
// TODO: all of those could/should be derived via a macro // TODO: all of those could/should be derived via a macro
// query clients // query clients
pub mod coconut_bandwidth_query_client; mod coconut_bandwidth_query_client;
pub mod dkg_query_client; mod dkg_query_client;
pub mod ephemera_query_client; mod ephemera_query_client;
pub mod group_query_client; mod group_query_client;
pub mod mixnet_query_client; mod mixnet_query_client;
pub mod multisig_query_client; mod multisig_query_client;
pub mod name_service_query_client; mod name_service_query_client;
pub mod sp_directory_query_client; mod sp_directory_query_client;
pub mod vesting_query_client; mod vesting_query_client;
// signing clients // signing clients
pub mod coconut_bandwidth_signing_client; mod coconut_bandwidth_signing_client;
pub mod dkg_signing_client; mod dkg_signing_client;
pub mod ephemera_signing_client; mod ephemera_signing_client;
pub mod group_signing_client; mod group_signing_client;
pub mod mixnet_signing_client; mod mixnet_signing_client;
pub mod multisig_signing_client; mod multisig_signing_client;
pub mod name_service_signing_client; mod name_service_signing_client;
pub mod sp_directory_signing_client; mod sp_directory_signing_client;
pub mod vesting_signing_client; mod vesting_signing_client;
// re-export query traits // re-export query traits
pub use coconut_bandwidth_query_client::{ pub use coconut_bandwidth_query_client::{
@@ -6,8 +6,8 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient; use crate::nyxd::CosmWasmClient;
use async_trait::async_trait; use async_trait::async_trait;
use cw3::{ use cw3::{
ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterDetail, ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterListResponse,
VoterListResponse, VoterResponse, VoterResponse,
}; };
use cw_utils::ThresholdResponse; use cw_utils::ThresholdResponse;
use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg; use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg;
@@ -114,26 +114,6 @@ pub trait PagedMultisigQueryClient: MultisigQueryClient {
Ok(proposals) Ok(proposals)
} }
async fn get_all_voters(&self) -> Result<Vec<VoterDetail>, NyxdError> {
let mut voters = Vec::new();
let mut start_after = None;
loop {
let mut paged_response = self.list_voters(start_after.take(), None).await?;
let last_voter = paged_response.voters.last().map(|prop| prop.addr.clone());
voters.append(&mut paged_response.voters);
if let Some(start_after_res) = last_voter {
start_after = Some(start_after_res)
} else {
break;
}
}
Ok(voters)
}
} }
#[async_trait] #[async_trait]
@@ -52,6 +52,10 @@ use wasmtimer::tokio::sleep;
pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4); pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4);
pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60);
#[cfg(feature = "http-client")]
#[async_trait]
impl CosmWasmClient for cosmrs::rpc::HttpClient {}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait CosmWasmClient: TendermintRpcClient { pub trait CosmWasmClient: TendermintRpcClient {
@@ -518,7 +522,3 @@ pub trait CosmWasmClient: TendermintRpcClient {
res.try_into() res.try_into()
} }
} }
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<T> CosmWasmClient for T where T: TendermintRpcClient {}
@@ -425,7 +425,7 @@ where
amount: amount.into_iter().map(Into::into).collect(), amount: amount.into_iter().map(Into::into).collect(),
} }
.to_any() .to_any()
.map_err(|_| NyxdError::SerializationError("MsgSend".to_owned())) .map_err(|_| NyxdError::SerializationError("MsgExecuteContract".to_owned()))
}) })
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient; use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient};
use crate::nyxd::error::NyxdError; use crate::nyxd::error::NyxdError;
use crate::nyxd::{Config, GasPrice, Hash, Height}; use crate::nyxd::{Config, GasPrice, Hash, Height};
use crate::rpc::TendermintRpcClient; use crate::rpc::TendermintRpcClient;
@@ -26,7 +26,6 @@ use cosmrs::rpc::{HttpClient, HttpClientUrl};
pub mod client_traits; pub mod client_traits;
mod helpers; mod helpers;
pub mod logs; pub mod logs;
pub mod module_traits;
pub mod types; pub mod types;
#[derive(Debug)] #[derive(Debug)]
@@ -330,6 +329,14 @@ where
} }
} }
#[async_trait]
impl<C, S> CosmWasmClient for MaybeSigningClient<C, S>
where
C: TendermintRpcClient + Send + Sync,
S: Send + Sync,
{
}
#[async_trait] #[async_trait]
impl<C, S> SigningCosmWasmClient for MaybeSigningClient<C, S> impl<C, S> SigningCosmWasmClient for MaybeSigningClient<C, S>
where where
@@ -1,8 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod slashing;
pub mod staking;
pub use staking::query::StakingQueryClient;
// pub use slashing::query
@@ -1,4 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod query;
@@ -1,2 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
@@ -1,8 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod query;
pub use cosmrs::staking::{
QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse, Validator,
};
@@ -1,78 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::{QueryHistoricalInfoResponse, QueryValidatorResponse, QueryValidatorsResponse};
use crate::nyxd::error::NyxdError;
use crate::nyxd::{CosmWasmClient, PageRequest};
use async_trait::async_trait;
use cosmrs::proto::cosmos::staking::v1beta1::{
QueryHistoricalInfoRequest as ProtoQueryHistoricalInfoRequest,
QueryHistoricalInfoResponse as ProtoQueryHistoricalInfoResponse,
QueryValidatorRequest as ProtoQueryValidatorRequest,
QueryValidatorResponse as ProtoQueryValidatorResponse,
QueryValidatorsRequest as ProtoQueryValidatorsRequest,
QueryValidatorsResponse as ProtoQueryValidatorsResponse,
};
use cosmrs::staking::{QueryHistoricalInfoRequest, QueryValidatorRequest, QueryValidatorsRequest};
use cosmrs::AccountId;
// TODO: change trait restriction from `CosmWasmClient` to `TendermintRpcClient`
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait StakingQueryClient: CosmWasmClient {
async fn historical_info(&self, height: i64) -> Result<QueryHistoricalInfoResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/HistoricalInfo".to_owned());
let req = QueryHistoricalInfoRequest { height };
let res = self
.make_abci_query::<ProtoQueryHistoricalInfoRequest, ProtoQueryHistoricalInfoResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
async fn validator(
&self,
validator_addr: AccountId,
) -> Result<QueryValidatorResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/Validator".to_owned());
let req = QueryValidatorRequest { validator_addr };
let res = self
.make_abci_query::<ProtoQueryValidatorRequest, ProtoQueryValidatorResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
async fn validators(
&self,
status: String,
pagination: Option<PageRequest>,
) -> Result<QueryValidatorsResponse, NyxdError> {
let path = Some("/cosmos.staking.v1beta1.Query/Validators".to_owned());
let req = QueryValidatorsRequest { status, pagination };
let res = self
.make_abci_query::<ProtoQueryValidatorsRequest, ProtoQueryValidatorsResponse>(
path,
req.into(),
)
.await?;
Ok(res.try_into()?)
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<T> StakingQueryClient for T where T: CosmWasmClient {}
@@ -1,13 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::TxResponse;
pub fn find_tx_attribute(tx: &TxResponse, event_type: &str, attribute_key: &str) -> Option<String> {
let event = tx.tx_result.events.iter().find(|e| e.kind == event_type)?;
let attribute = event
.attributes
.iter()
.find(|attr| attr.key == attribute_key)?;
Some(attribute.value.clone())
}
@@ -29,41 +29,31 @@ use tendermint_rpc::endpoint::*;
use tendermint_rpc::{Error as TendermintRpcError, Order}; use tendermint_rpc::{Error as TendermintRpcError, Order};
use url::Url; use url::Url;
pub use crate::nyxd::{ pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient};
cosmwasm_client::{ pub use crate::nyxd::fee::Fee;
client_traits::{CosmWasmClient, SigningCosmWasmClient},
module_traits::{self, StakingQueryClient},
},
fee::Fee,
};
pub use crate::rpc::TendermintRpcClient; pub use crate::rpc::TendermintRpcClient;
pub use coin::Coin; pub use coin::Coin;
pub use cosmrs::{ pub use cosmrs::bank::MsgSend;
bank::MsgSend, pub use cosmrs::tendermint::abci::{
bip32, response::DeliverTx, types::ExecTxResult, Event, EventAttribute,
crypto::PublicKey,
query::{PageRequest, PageResponse},
tendermint::{
abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute},
block::Height,
hash::{self, Algorithm, Hash},
validator::Info as TendermintValidatorInfo,
Time as TendermintTime,
},
tx::{self, Msg},
AccountId, Any, Coin as CosmosCoin, Denom, Gas,
}; };
pub use cosmrs::tendermint::block::Height;
pub use cosmrs::tendermint::hash::{self, Algorithm, Hash};
pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo;
pub use cosmrs::tendermint::Time as TendermintTime;
pub use cosmrs::tx::Msg;
pub use cosmrs::tx::{self};
pub use cosmrs::Coin as CosmosCoin;
pub use cosmrs::Gas;
pub use cosmrs::{bip32, AccountId, Denom};
pub use cosmwasm_std::Coin as CosmWasmCoin; pub use cosmwasm_std::Coin as CosmWasmCoin;
pub use cw2;
pub use cw3;
pub use cw4;
pub use cw_controllers;
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
pub use tendermint_rpc::{ pub use tendermint_rpc::{
endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse}, endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse},
query::Query, query::Query,
Paging, Request, Response, SimpleRequest, Paging,
}; };
pub use tendermint_rpc::{Request, Response, SimpleRequest};
#[cfg(feature = "http-client")] #[cfg(feature = "http-client")]
use crate::http_client; use crate::http_client;
@@ -77,7 +67,6 @@ pub mod contract_traits;
pub mod cosmwasm_client; pub mod cosmwasm_client;
pub mod error; pub mod error;
pub mod fee; pub mod fee;
pub mod helpers;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Config { pub struct Config {
@@ -103,14 +92,6 @@ impl Config {
} }
} }
impl TryFrom<NymNetworkDetails> for Config {
type Error = NyxdError;
fn try_from(value: NymNetworkDetails) -> Result<Self, Self::Error> {
Config::try_from_nym_network_details(&value)
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct NyxdClient<C, S = NoSigner> { pub struct NyxdClient<C, S = NoSigner> {
client: MaybeSigningClient<C, S>, client: MaybeSigningClient<C, S>,
@@ -742,7 +723,7 @@ where
where where
H: Into<Height> + Send, H: Into<Height> + Send,
{ {
TendermintRpcClient::validators(&self.client, height, paging).await self.client.validators(height, paging).await
} }
async fn latest_consensus_params( async fn latest_consensus_params(
@@ -817,6 +798,14 @@ where
} }
} }
#[async_trait]
impl<C, S> CosmWasmClient for NyxdClient<C, S>
where
C: TendermintRpcClient + Send + Sync,
S: Send + Sync,
{
}
impl<C, S> OfflineSigner for NyxdClient<C, S> impl<C, S> OfflineSigner for NyxdClient<C, S>
where where
S: OfflineSigner, S: OfflineSigner,
-1
View File
@@ -3,7 +3,6 @@ name = "nym-coconut-interface"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Crutch library until there is proper SerDe support for coconut structs" description = "Crutch library until there is proper SerDe support for coconut structs"
license.workspace = true
[dependencies] [dependencies]
bs58 = "0.4.0" bs58 = "0.4.0"
+11 -13
View File
@@ -14,21 +14,17 @@ pub use nym_coconut::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar,
prepare_blind_sign, prove_bandwidth_credential, Attribute, Base58, BlindSignRequest, prepare_blind_sign, prove_bandwidth_credential, Attribute, Base58, BlindSignRequest,
BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute,
PublicAttribute, SecretKey, Signature, SignatureShare, Theta, VerificationKey, PublicAttribute, Signature, SignatureShare, Theta, VerificationKey,
}; };
#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)]
pub struct Credential { pub struct Credential {
#[getset(get = "pub")] #[getset(get = "pub")]
n_params: u32, n_params: u32,
#[getset(get = "pub")] #[getset(get = "pub")]
theta: Theta, theta: Theta,
voucher_value: u64, voucher_value: u64,
voucher_info: String, voucher_info: String,
#[getset(get = "pub")] #[getset(get = "pub")]
epoch_id: u64, epoch_id: u64,
} }
@@ -68,12 +64,14 @@ impl Credential {
pub fn verify(&self, verification_key: &VerificationKey) -> bool { pub fn verify(&self, verification_key: &VerificationKey) -> bool {
let params = Parameters::new(self.n_params).unwrap(); let params = Parameters::new(self.n_params).unwrap();
let public_attributes = [
let hashed_value = hash_to_scalar(self.voucher_value.to_string()); self.voucher_value.to_string().as_bytes(),
let hashed_info = hash_to_scalar(&self.voucher_info); self.voucher_info.as_bytes(),
let public_attributes = &[&hashed_value, &hashed_info]; ]
.iter()
nym_coconut::verify_credential(&params, verification_key, &self.theta, public_attributes) .map(hash_to_scalar)
.collect::<Vec<Attribute>>();
nym_coconut::verify_credential(&params, verification_key, &self.theta, &public_attributes)
} }
pub fn as_bytes(&self) -> Vec<u8> { pub fn as_bytes(&self) -> Vec<u8> {
@@ -182,8 +180,8 @@ mod tests {
&params, &params,
&verification_key, &verification_key,
&signature, &signature,
&serial_number, serial_number,
&binding_number, binding_number,
) )
.unwrap(); .unwrap();
let credential = Credential::new(4, theta, voucher_value, voucher_info, 42); let credential = Credential::new(4, theta, voucher_value, voucher_info, 42);
-1
View File
@@ -3,7 +3,6 @@ name = "nym-cli-commands"
version = "1.0.0" version = "1.0.0"
authors.workspace = true authors.workspace = true
edition = "2021" edition = "2021"
license.workspace = true
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
@@ -26,10 +26,6 @@ pub struct Args {
} }
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
if args.amount == 0 {
bail!("did not specify credential amount")
}
let loaded = CommonConfigsWrapper::try_load(args.client_config)?; let loaded = CommonConfigsWrapper::try_load(args.client_config)?;
if let Ok(id) = loaded.try_get_id() { if let Ok(id) = loaded.try_get_id() {
@@ -6,7 +6,7 @@ use log::{debug, info};
use std::str::FromStr; use std::str::FromStr;
use nym_coconut_dkg_common::msg::InstantiateMsg; use nym_coconut_dkg_common::msg::InstantiateMsg;
use nym_coconut_dkg_common::types::{TimeConfiguration, DEFAULT_DEALINGS}; use nym_coconut_dkg_common::types::TimeConfiguration;
use nym_validator_client::nyxd::AccountId; use nym_validator_client::nyxd::AccountId;
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
@@ -93,7 +93,6 @@ pub async fn generate(args: Args) {
multisig_addr: multisig_addr.to_string(), multisig_addr: multisig_addr.to_string(),
time_configuration: Some(time_configuration), time_configuration: Some(time_configuration),
mix_denom, mix_denom,
key_size: DEFAULT_DEALINGS as u32,
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {:?}", instantiate_msg);
+1 -2
View File
@@ -3,7 +3,6 @@ name = "nym-config"
version = "0.1.0" version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"] authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -18,4 +17,4 @@ url = { workspace = true }
nym-network-defaults = { path = "../network-defaults" } nym-network-defaults = { path = "../network-defaults" }
[features] [features]
default = ["dirs"] default = ["dirs"]
+1 -1
View File
@@ -73,7 +73,7 @@ where
P: AsRef<Path>, P: AsRef<Path>,
{ {
let path = path.as_ref(); let path = path.as_ref();
log::info!("saving config file to {}", path.display()); log::debug!("trying to save config file to {}", path.display());
if let Some(parent) = path.parent() { if let Some(parent) = path.parent() {
create_dir_all(parent)?; create_dir_all(parent)?;
@@ -2,7 +2,6 @@
name = "nym-coconut-bandwidth-contract-common" name = "nym-coconut-bandwidth-contract-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -13,4 +12,4 @@ cw2 = { workspace = true, optional = true }
nym-multisig-contract-common = { path = "../multisig-contract" } nym-multisig-contract-common = { path = "../multisig-contract" }
[features] [features]
schema = ["cw2"] schema = ["cw2"]
@@ -4,9 +4,6 @@
// event types // event types
pub const DEPOSITED_FUNDS_EVENT_TYPE: &str = "deposited-funds"; pub const DEPOSITED_FUNDS_EVENT_TYPE: &str = "deposited-funds";
// a 'wasm-' prefix is added to all cosmwasm events
pub const COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE: &str = "wasm-deposited-funds";
// attributes that are used in multiple places // attributes that are used in multiple places
pub const DEPOSIT_VALUE: &str = "deposit-value"; pub const DEPOSIT_VALUE: &str = "deposit-value";
pub const DEPOSIT_INFO: &str = "deposit-info"; pub const DEPOSIT_INFO: &str = "deposit-info";
@@ -2,7 +2,6 @@
name = "nym-coconut-dkg-common" name = "nym-coconut-dkg-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -10,11 +9,9 @@ license.workspace = true
cosmwasm-schema = { workspace = true } cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true } cosmwasm-std = { workspace = true }
cw-utils = { workspace = true } cw-utils = { workspace = true }
cw2 = { workspace = true }
cw4 = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" } contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
nym-multisig-contract-common = { path = "../multisig-contract" } nym-multisig-contract-common = { path = "../multisig-contract" }
[features] [features]
schema = [] schema = []
@@ -1,7 +1,7 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::types::{EncodedBTEPublicKeyWithProof, NodeIndex}; use crate::types::{ContractSafeBytes, EncodedBTEPublicKeyWithProof, NodeIndex};
use cosmwasm_schema::cw_serde; use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr; use cosmwasm_std::Addr;
@@ -9,7 +9,6 @@ use cosmwasm_std::Addr;
pub struct DealerDetails { pub struct DealerDetails {
pub address: Addr, pub address: Addr,
pub bte_public_key_with_proof: EncodedBTEPublicKeyWithProof, pub bte_public_key_with_proof: EncodedBTEPublicKeyWithProof,
pub ed25519_identity: String,
pub announce_address: String, pub announce_address: String,
pub assigned_index: NodeIndex, pub assigned_index: NodeIndex,
} }
@@ -65,3 +64,38 @@ impl PagedDealerResponse {
} }
} }
} }
#[cw_serde]
pub struct ContractDealing {
pub dealing: ContractSafeBytes,
pub dealer: Addr,
}
impl ContractDealing {
pub fn new(dealing: ContractSafeBytes, dealer: Addr) -> Self {
ContractDealing { dealing, dealer }
}
}
#[cw_serde]
pub struct PagedDealingsResponse {
pub dealings: Vec<ContractDealing>,
pub per_page: usize,
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
pub start_next_after: Option<Addr>,
}
impl PagedDealingsResponse {
pub fn new(
dealings: Vec<ContractDealing>,
per_page: usize,
start_next_after: Option<Addr>,
) -> Self {
PagedDealingsResponse {
dealings,
per_page,
start_next_after,
}
}
}
@@ -1,284 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::types::{ChunkIndex, DealingIndex, EpochId, PartialContractDealingData};
use contracts_common::dealings::ContractSafeBytes;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use std::collections::{BTreeMap, HashMap};
/// Defines the maximum size of a dealing chunk. Currently set to 2kB
pub const MAX_DEALING_CHUNK_SIZE: usize = 2048;
/// Defines the maximum size of a full dealing.
/// Currently set to 100kB (which is enough for a dealing created for 100 parties)
pub const MAX_DEALING_SIZE: usize = 102400;
pub const MAX_DEALING_CHUNKS: usize = MAX_DEALING_SIZE / MAX_DEALING_CHUNK_SIZE;
// 2 public attributes, 2 private attributes, 1 fixed for coconut credential
pub const DEFAULT_DEALINGS: usize = 2 + 2 + 1;
pub fn chunk_dealing(
dealing_index: DealingIndex,
dealing_bytes: Vec<u8>,
chunk_size: usize,
) -> HashMap<ChunkIndex, PartialContractDealing> {
let mut chunks = HashMap::new();
for (chunk_index, chunk) in dealing_bytes.chunks(chunk_size).enumerate() {
let chunk = PartialContractDealing {
dealing_index,
chunk_index: chunk_index as ChunkIndex,
data: ContractSafeBytes(chunk.to_vec()),
};
chunks.insert(chunk_index as ChunkIndex, chunk);
}
chunks
}
#[cw_serde]
#[derive(Copy)]
pub struct DealingChunkInfo {
pub size: usize,
}
impl DealingChunkInfo {
pub fn new(size: usize) -> Self {
DealingChunkInfo { size }
}
pub fn construct(dealing_len: usize, chunk_size: usize) -> Vec<Self> {
let (full_chunks, overflow) = (dealing_len / chunk_size, dealing_len % chunk_size);
let mut chunks = Vec::new();
for _ in 0..full_chunks {
chunks.push(DealingChunkInfo::new(chunk_size));
}
if overflow != 0 {
chunks.push(DealingChunkInfo::new(overflow));
}
chunks
}
}
#[cw_serde]
#[derive(Copy)]
pub struct SubmittedChunk {
pub info: DealingChunkInfo,
pub status: ChunkSubmissionStatus,
}
#[cw_serde]
#[derive(Default, Copy)]
pub struct ChunkSubmissionStatus {
// this field is updated by the contract itself to indicate when this particular chunk has been received
pub submission_height: Option<u64>,
}
impl ChunkSubmissionStatus {
pub fn submitted(&self) -> bool {
self.submission_height.is_some()
}
}
impl From<DealingChunkInfo> for SubmittedChunk {
fn from(value: DealingChunkInfo) -> Self {
SubmittedChunk::new(value)
}
}
impl SubmittedChunk {
pub fn new(info: DealingChunkInfo) -> Self {
SubmittedChunk {
info,
status: Default::default(),
}
}
pub fn submitted(&self) -> bool {
self.status.submitted()
}
}
#[cw_serde]
pub struct DealingMetadata {
pub dealing_index: DealingIndex,
pub submitted_chunks: BTreeMap<ChunkIndex, SubmittedChunk>,
}
impl DealingMetadata {
pub fn new(dealing_index: DealingIndex, chunks: Vec<DealingChunkInfo>) -> Self {
DealingMetadata {
dealing_index,
submitted_chunks: chunks
.into_iter()
.enumerate()
.map(|(id, chunk)| (id as ChunkIndex, chunk.into()))
.collect(),
}
}
pub fn is_complete(&self) -> bool {
self.submitted_chunks.values().all(|c| c.submitted())
}
pub fn total_size(&self) -> usize {
self.submitted_chunks.values().map(|c| c.info.size).sum()
}
pub fn submission_statuses(&self) -> BTreeMap<ChunkIndex, ChunkSubmissionStatus> {
self.submitted_chunks
.iter()
.map(|(id, c)| (*id, c.status))
.collect()
}
}
#[cw_serde]
pub struct PartialContractDealing {
pub dealing_index: DealingIndex,
pub chunk_index: ChunkIndex,
pub data: PartialContractDealingData,
}
impl PartialContractDealing {
pub fn new(
dealing_index: DealingIndex,
chunk_index: ChunkIndex,
data: PartialContractDealingData,
) -> Self {
PartialContractDealing {
dealing_index,
chunk_index,
data,
}
}
}
#[cw_serde]
pub struct DealingMetadataResponse {
pub epoch_id: EpochId,
pub dealer: Addr,
pub dealing_index: DealingIndex,
pub metadata: Option<DealingMetadata>,
}
#[cw_serde]
pub struct DealingChunkResponse {
pub epoch_id: EpochId,
pub dealer: Addr,
pub dealing_index: DealingIndex,
pub chunk_index: ChunkIndex,
pub chunk: Option<PartialContractDealingData>,
}
#[cw_serde]
pub struct DealingChunkStatusResponse {
pub epoch_id: EpochId,
pub dealer: Addr,
pub dealing_index: DealingIndex,
pub chunk_index: ChunkIndex,
pub status: ChunkSubmissionStatus,
}
#[cw_serde]
pub struct DealingStatusResponse {
pub epoch_id: EpochId,
pub dealer: Addr,
pub dealing_index: DealingIndex,
pub status: DealingStatus,
}
#[cw_serde]
pub struct DealingStatus {
pub has_metadata: bool,
pub fully_submitted: bool,
pub chunk_submission_status: BTreeMap<ChunkIndex, ChunkSubmissionStatus>,
}
impl From<Option<DealingMetadata>> for DealingStatus {
fn from(metadata: Option<DealingMetadata>) -> Self {
DealingStatus {
has_metadata: metadata.is_some(),
fully_submitted: metadata
.as_ref()
.map(|m| m.is_complete())
.unwrap_or_default(),
chunk_submission_status: metadata
.map(|m| m.submission_statuses())
.unwrap_or_default(),
}
}
}
#[cw_serde]
pub struct DealerDealingsStatusResponse {
pub epoch_id: EpochId,
pub dealer: Addr,
pub all_dealings_fully_submitted: bool,
pub dealing_submission_status: BTreeMap<DealingIndex, DealingStatus>,
}
impl DealerDealingsStatusResponse {
pub fn full_dealings(&self) -> usize {
self.dealing_submission_status
.values()
.filter(|s| s.fully_submitted)
.count()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn chunking_dealings() {
const CHUNK_SIZE: usize = 512;
let test_cases = [
(CHUNK_SIZE - 10, CHUNK_SIZE, 1),
(CHUNK_SIZE, CHUNK_SIZE, 1),
(CHUNK_SIZE + 10, CHUNK_SIZE, 2),
(CHUNK_SIZE * 2, CHUNK_SIZE, 2),
(CHUNK_SIZE * 2 + 1, CHUNK_SIZE, 3),
(CHUNK_SIZE * 10 + 42, CHUNK_SIZE, 11),
];
for (dealing_len, chunk_size, expected_chunks) in test_cases {
let chunks = DealingChunkInfo::construct(dealing_len, chunk_size);
assert_eq!(expected_chunks, chunks.len());
assert_eq!(dealing_len, chunks.iter().map(|c| c.size).sum::<usize>());
let mut expected_last = dealing_len % chunk_size;
if expected_last == 0 {
expected_last = chunk_size;
}
assert_eq!(chunks.last().unwrap().size, expected_last);
}
}
}
@@ -1,8 +1,4 @@
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod dealer; pub mod dealer;
pub mod dealing;
pub mod event_attributes; pub mod event_attributes;
pub mod msg; pub mod msg;
pub mod types; pub mod types;
@@ -1,23 +1,16 @@
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::dealing::{DealingChunkInfo, PartialContractDealing}; use crate::types::{ContractSafeBytes, EncodedBTEPublicKeyWithProof, EpochId, TimeConfiguration};
use crate::types::{
ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, EpochId, TimeConfiguration,
};
use crate::verification_key::VerificationKeyShare; use crate::verification_key::VerificationKeyShare;
use contracts_common::IdentityKey;
use cosmwasm_schema::cw_serde; use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
#[cfg(feature = "schema")] #[cfg(feature = "schema")]
use crate::{ use crate::{
dealer::{DealerDetailsResponse, PagedDealerResponse}, dealer::{DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse},
dealing::{ types::{Epoch, InitialReplacementData},
DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, verification_key::PagedVKSharesResponse,
DealingMetadataResponse, DealingStatusResponse,
},
types::{Epoch, InitialReplacementData, State},
verification_key::{PagedVKSharesResponse, VkShareResponse},
}; };
#[cfg(feature = "schema")] #[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses; use cosmwasm_schema::QueryResponses;
@@ -28,31 +21,18 @@ pub struct InstantiateMsg {
pub multisig_addr: String, pub multisig_addr: String,
pub time_configuration: Option<TimeConfiguration>, pub time_configuration: Option<TimeConfiguration>,
pub mix_denom: String, pub mix_denom: String,
/// Specifies the number of elements in the derived keys
pub key_size: u32,
} }
#[cw_serde] #[cw_serde]
pub enum ExecuteMsg { pub enum ExecuteMsg {
// we could have just re-used AdvanceEpochState, but imo an explicit message is better
InitiateDkg {},
RegisterDealer { RegisterDealer {
bte_key_with_proof: EncodedBTEPublicKeyWithProof, bte_key_with_proof: EncodedBTEPublicKeyWithProof,
identity_key: IdentityKey,
announce_address: String, announce_address: String,
resharing: bool, resharing: bool,
}, },
CommitDealingsMetadata { CommitDealing {
dealing_index: DealingIndex, dealing_bytes: ContractSafeBytes,
chunks: Vec<DealingChunkInfo>,
resharing: bool,
},
CommitDealingsChunk {
chunk: PartialContractDealing,
resharing: bool, resharing: bool,
}, },
@@ -62,7 +42,8 @@ pub enum ExecuteMsg {
}, },
VerifyVerificationKeyShare { VerifyVerificationKeyShare {
owner: String, // TODO: this should be using a String...
owner: Addr,
resharing: bool, resharing: bool,
}, },
@@ -74,9 +55,6 @@ pub enum ExecuteMsg {
#[cw_serde] #[cw_serde]
#[cfg_attr(feature = "schema", derive(QueryResponses))] #[cfg_attr(feature = "schema", derive(QueryResponses))]
pub enum QueryMsg { pub enum QueryMsg {
#[cfg_attr(feature = "schema", returns(State))]
GetState {},
#[cfg_attr(feature = "schema", returns(Epoch))] #[cfg_attr(feature = "schema", returns(Epoch))]
GetCurrentEpochState {}, GetCurrentEpochState {},
@@ -101,53 +79,19 @@ pub enum QueryMsg {
start_after: Option<String>, start_after: Option<String>,
}, },
#[cfg_attr(feature = "schema", returns(DealingMetadataResponse))] #[cfg_attr(feature = "schema", returns(PagedDealingsResponse))]
GetDealingsMetadata { GetDealing {
epoch_id: EpochId, idx: u64,
dealer: String, limit: Option<u32>,
dealing_index: DealingIndex, start_after: Option<String>,
}, },
#[cfg_attr(feature = "schema", returns(DealerDealingsStatusResponse))]
GetDealerDealingsStatus { epoch_id: EpochId, dealer: String },
#[cfg_attr(feature = "schema", returns(DealingStatusResponse))]
GetDealingStatus {
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
},
#[cfg_attr(feature = "schema", returns(DealingChunkStatusResponse))]
GetDealingChunkStatus {
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
chunk_index: ChunkIndex,
},
#[cfg_attr(feature = "schema", returns(DealingChunkResponse))]
GetDealingChunk {
epoch_id: EpochId,
dealer: String,
dealing_index: DealingIndex,
chunk_index: ChunkIndex,
},
#[cfg_attr(feature = "schema", returns(VkShareResponse))]
GetVerificationKey { epoch_id: EpochId, owner: String },
#[cfg_attr(feature = "schema", returns(PagedVKSharesResponse))] #[cfg_attr(feature = "schema", returns(PagedVKSharesResponse))]
GetVerificationKeys { GetVerificationKeys {
epoch_id: EpochId, epoch_id: EpochId,
limit: Option<u32>, limit: Option<u32>,
start_after: Option<String>, start_after: Option<String>,
}, },
/// Gets the stored contract version information that's required by the CW2 spec interface for migrations.
#[serde(rename = "get_cw2_contract_version")]
#[cfg_attr(feature = "schema", returns(cw2::ContractVersion))]
GetCW2ContractVersion {},
} }
#[cw_serde] #[cw_serde]
@@ -8,18 +8,14 @@ use std::str::FromStr;
pub use crate::dealer::{DealerDetails, PagedDealerResponse}; pub use crate::dealer::{DealerDetails, PagedDealerResponse};
pub use contracts_common::dealings::ContractSafeBytes; pub use contracts_common::dealings::ContractSafeBytes;
pub use cosmwasm_std::{Addr, Coin, Timestamp}; pub use cosmwasm_std::{Addr, Coin, Timestamp};
pub use cw4::Cw4Contract;
pub type EncodedBTEPublicKeyWithProof = String; pub type EncodedBTEPublicKeyWithProof = String;
pub type EncodedBTEPublicKeyWithProofRef<'a> = &'a str; pub type EncodedBTEPublicKeyWithProofRef<'a> = &'a str;
pub type NodeIndex = u64; pub type NodeIndex = u64;
pub type EpochId = u64; pub type EpochId = u64;
pub type DealingIndex = u32;
// we really don't need to hold more data than that (even u8 would have been enough), // 2 public attributes, 2 private attributes, 1 fixed for coconut credential
// but explicitly make it different type than `DealingIndex` so type system would detect any pub const TOTAL_DEALINGS: usize = 2 + 2 + 1;
// accidental misuses
pub type ChunkIndex = u16;
pub type PartialContractDealingData = ContractSafeBytes;
#[cw_serde] #[cw_serde]
pub struct InitialReplacementData { pub struct InitialReplacementData {
@@ -77,23 +73,13 @@ impl Default for TimeConfiguration {
} }
} }
#[cw_serde]
pub struct State {
pub mix_denom: String,
pub multisig_addr: Addr,
pub group_addr: Cw4Contract,
/// Specifies the number of elements in the derived keys
pub key_size: u32,
}
#[cw_serde] #[cw_serde]
#[derive(Copy, Default)] #[derive(Copy, Default)]
pub struct Epoch { pub struct Epoch {
pub state: EpochState, pub state: EpochState,
pub epoch_id: EpochId, pub epoch_id: EpochId,
pub time_configuration: TimeConfiguration, pub time_configuration: TimeConfiguration,
pub finish_timestamp: Option<Timestamp>, pub finish_timestamp: Timestamp,
} }
impl Epoch { impl Epoch {
@@ -104,40 +90,36 @@ impl Epoch {
current_timestamp: Timestamp, current_timestamp: Timestamp,
) -> Self { ) -> Self {
let duration = match state { let duration = match state {
EpochState::WaitingInitialisation => None,
EpochState::PublicKeySubmission { .. } => { EpochState::PublicKeySubmission { .. } => {
Some(time_configuration.public_key_submission_time_secs) time_configuration.public_key_submission_time_secs
}
EpochState::DealingExchange { .. } => {
Some(time_configuration.dealing_exchange_time_secs)
} }
EpochState::DealingExchange { .. } => time_configuration.dealing_exchange_time_secs,
EpochState::VerificationKeySubmission { .. } => { EpochState::VerificationKeySubmission { .. } => {
Some(time_configuration.verification_key_submission_time_secs) time_configuration.verification_key_submission_time_secs
} }
EpochState::VerificationKeyValidation { .. } => { EpochState::VerificationKeyValidation { .. } => {
Some(time_configuration.verification_key_validation_time_secs) time_configuration.verification_key_validation_time_secs
} }
EpochState::VerificationKeyFinalization { .. } => { EpochState::VerificationKeyFinalization { .. } => {
Some(time_configuration.verification_key_finalization_time_secs) time_configuration.verification_key_finalization_time_secs
} }
EpochState::InProgress => Some(time_configuration.in_progress_time_secs), EpochState::InProgress => time_configuration.in_progress_time_secs,
}; };
Epoch { Epoch {
state, state,
epoch_id, epoch_id,
time_configuration, time_configuration,
finish_timestamp: duration.map(|d| current_timestamp.plus_seconds(d)), finish_timestamp: current_timestamp.plus_seconds(duration),
} }
} }
pub fn final_timestamp_secs(&self) -> Option<u64> { pub fn final_timestamp_secs(&self) -> u64 {
let mut finish = self.finish_timestamp?.seconds(); let mut finish = self.finish_timestamp.seconds();
let time_configuration = self.time_configuration; let time_configuration = self.time_configuration;
let mut curr_epoch_state = self.state; let mut curr_epoch_state = self.state;
while let Some(state) = curr_epoch_state.next() { while let Some(state) = curr_epoch_state.next() {
curr_epoch_state = state; curr_epoch_state = state;
let adding = match curr_epoch_state { let adding = match curr_epoch_state {
EpochState::WaitingInitialisation => return None,
EpochState::PublicKeySubmission { .. } => { EpochState::PublicKeySubmission { .. } => {
time_configuration.public_key_submission_time_secs time_configuration.public_key_submission_time_secs
} }
@@ -155,13 +137,12 @@ impl Epoch {
}; };
finish += adding; finish += adding;
} }
Some(finish) finish
} }
} }
// currently (it is still extremely likely to change, we might be able to get rid of verification key-related complaints), // currently (it is still extremely likely to change, we might be able to get rid of verification key-related complaints),
// the epoch can be in the following states (in order): // the epoch can be in the following states (in order):
// 0. WaitingInitialisation -> the contract has been instantiated, but awaits for the admin to kick off the process (group members might still be getting added)
// 1. PublicKeySubmission -> potential dealers are submitting their BTE and ed25519 public keys to participate in dealing exchange // 1. PublicKeySubmission -> potential dealers are submitting their BTE and ed25519 public keys to participate in dealing exchange
// 2. DealingExchange -> the actual (off-chain) dealing exchange is happening // 2. DealingExchange -> the actual (off-chain) dealing exchange is happening
// 3. ComplaintSubmission -> receivers submitting evidence of other dealers sending malformed data // 3. ComplaintSubmission -> receivers submitting evidence of other dealers sending malformed data
@@ -175,7 +156,6 @@ impl Epoch {
#[cw_serde] #[cw_serde]
#[derive(Copy)] #[derive(Copy)]
pub enum EpochState { pub enum EpochState {
WaitingInitialisation,
PublicKeySubmission { resharing: bool }, PublicKeySubmission { resharing: bool },
DealingExchange { resharing: bool }, DealingExchange { resharing: bool },
VerificationKeySubmission { resharing: bool }, VerificationKeySubmission { resharing: bool },
@@ -186,28 +166,25 @@ pub enum EpochState {
impl Default for EpochState { impl Default for EpochState {
fn default() -> Self { fn default() -> Self {
Self::WaitingInitialisation Self::PublicKeySubmission { resharing: false }
} }
} }
impl Display for EpochState { impl Display for EpochState {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
EpochState::WaitingInitialisation => write!(f, "Waiting for initialisation"),
EpochState::PublicKeySubmission { resharing } => { EpochState::PublicKeySubmission { resharing } => {
write!(f, "PublicKeySubmission (resharing: {resharing})") write!(f, "PublicKeySubmission with resharing {resharing}")
}
EpochState::DealingExchange { resharing } => {
write!(f, "DealingExchange (resharing: {resharing})")
} }
EpochState::DealingExchange { resharing } => write!(f, "DealingExchange {resharing}"),
EpochState::VerificationKeySubmission { resharing } => { EpochState::VerificationKeySubmission { resharing } => {
write!(f, "VerificationKeySubmission (resharing: {resharing})") write!(f, "VerificationKeySubmission with resharing {resharing}")
} }
EpochState::VerificationKeyValidation { resharing } => { EpochState::VerificationKeyValidation { resharing } => {
write!(f, "VerificationKeyValidation (resharing: {resharing})") write!(f, "VerificationKeyValidation with resharing {resharing}")
} }
EpochState::VerificationKeyFinalization { resharing } => { EpochState::VerificationKeyFinalization { resharing } => {
write!(f, "VerificationKeyFinalization (resharing: {resharing})") write!(f, "VerificationKeyFinalization with resharing {resharing}")
} }
EpochState::InProgress => write!(f, "InProgress"), EpochState::InProgress => write!(f, "InProgress"),
} }
@@ -215,13 +192,8 @@ impl Display for EpochState {
} }
impl EpochState { impl EpochState {
pub fn first() -> Self {
EpochState::PublicKeySubmission { resharing: false }
}
pub fn next(self) -> Option<Self> { pub fn next(self) -> Option<Self> {
match self { match self {
EpochState::WaitingInitialisation => None,
EpochState::PublicKeySubmission { resharing } => { EpochState::PublicKeySubmission { resharing } => {
Some(EpochState::DealingExchange { resharing }) Some(EpochState::DealingExchange { resharing })
} }
@@ -20,13 +20,6 @@ pub struct ContractVKShare {
pub verified: bool, pub verified: bool,
} }
#[cw_serde]
pub struct VkShareResponse {
pub owner: Addr,
pub epoch_id: EpochId,
pub share: Option<ContractVKShare>,
}
#[cw_serde] #[cw_serde]
pub struct PagedVKSharesResponse { pub struct PagedVKSharesResponse {
pub shares: Vec<ContractVKShare>, pub shares: Vec<ContractVKShare>,
@@ -43,10 +36,7 @@ pub fn to_cosmos_msg(
multisig_addr: String, multisig_addr: String,
expiration_time: Timestamp, expiration_time: Timestamp,
) -> StdResult<CosmosMsg> { ) -> StdResult<CosmosMsg> {
let verify_vk_share_req = ExecuteMsg::VerifyVerificationKeyShare { let verify_vk_share_req = ExecuteMsg::VerifyVerificationKeyShare { owner, resharing };
owner: owner.to_string(),
resharing,
};
let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute { let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: coconut_dkg_addr, contract_addr: coconut_dkg_addr,
msg: to_binary(&verify_vk_share_req)?, msg: to_binary(&verify_vk_share_req)?,
@@ -67,14 +57,7 @@ pub fn to_cosmos_msg(
Ok(msg) Ok(msg)
} }
// DKG SAFETY: pub fn owner_from_cosmos_msgs(msgs: &[CosmosMsg]) -> Option<Addr> {
// each legit verification proposal will only contain a single execute msg,
// if they have more than one, we can safely ignore it
pub fn owner_from_cosmos_msgs(msgs: &[CosmosMsg]) -> Option<String> {
if msgs.len() != 1 {
return None;
}
if let Some(CosmosMsg::Wasm(WasmMsg::Execute { if let Some(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: _, contract_addr: _,
msg, msg,
@@ -4,14 +4,14 @@
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::ops::{Deref, DerefMut}; use std::ops::Deref;
// some sane upper-bound size on byte sizes // some sane upper-bound size on byte sizes
// currently set to 128 bytes // currently set to 128 bytes
pub const MAX_DISPLAY_SIZE: usize = 128; pub const MAX_DISPLAY_SIZE: usize = 128;
// helps to transfer bytes between contract boundary to decrease amount of data sent accross // TODO: if we are to use this for different types, it might make sense to introduce something like
// after it's put to `Binary` // CommitmentTypeId field on the below for distinguishing different ones. it would somehow become part of the trait
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, JsonSchema)] #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, JsonSchema)]
pub struct ContractSafeBytes(pub Vec<u8>); pub struct ContractSafeBytes(pub Vec<u8>);
@@ -23,18 +23,6 @@ impl Deref for ContractSafeBytes {
} }
} }
impl DerefMut for ContractSafeBytes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<Vec<u8>> for ContractSafeBytes {
fn from(value: Vec<u8>) -> Self {
ContractSafeBytes(value)
}
}
impl Display for ContractSafeBytes { impl Display for ContractSafeBytes {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if !self.0.is_empty() { if !self.0.is_empty() {
@@ -2,7 +2,6 @@
name = "nym-ephemera-common" name = "nym-ephemera-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,4 +13,4 @@ cw-utils = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" } contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
[features] [features]
schema = [] schema = []
@@ -2,7 +2,6 @@
name = "nym-group-contract-common" name = "nym-group-contract-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2,7 +2,6 @@
name = "nym-multisig-contract-common" name = "nym-multisig-contract-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2,7 +2,6 @@
name = "nym-name-service-common" name = "nym-name-service-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -17,4 +16,4 @@ serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true } thiserror = { workspace = true }
[features] [features]
schema = ["cw2"] schema = ["cw2"]
@@ -2,7 +2,6 @@
name = "nym-service-provider-directory-common" name = "nym-service-provider-directory-common"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,4 +15,4 @@ nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
thiserror = { workspace = true } thiserror = { workspace = true }
[features] [features]
schema = ["cw2"] schema = ["cw2"]
+3 -4
View File
@@ -2,7 +2,6 @@
name = "nym-credential-storage" name = "nym-credential-storage"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,14 +13,14 @@ thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["sync"]} tokio = { version = "1.24.1", features = ["sync"]}
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true version = "0.5"
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
workspace = true version = "1.24.1"
features = [ "rt-multi-thread", "net", "signal", "fs" ] features = [ "rt-multi-thread", "net", "signal", "fs" ]
[build-dependencies] [build-dependencies]
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
-1
View File
@@ -2,7 +2,6 @@
name = "nym-credential-utils" name = "nym-credential-utils"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+9 -19
View File
@@ -5,9 +5,7 @@ use nym_bandwidth_controller::acquire::state::State;
use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_client_core::config::disk_persistence::CommonClientPaths;
use nym_config::DEFAULT_DATA_DIR; use nym_config::DEFAULT_DATA_DIR;
use nym_credential_storage::persistent_storage::PersistentStorage; use nym_credential_storage::persistent_storage::PersistentStorage;
use nym_validator_client::nyxd::contract_traits::{ use nym_validator_client::nyxd::contract_traits::{CoconutBandwidthSigningClient, DkgQueryClient};
dkg_query_client::EpochState, CoconutBandwidthSigningClient, DkgQueryClient,
};
use nym_validator_client::nyxd::Coin; use nym_validator_client::nyxd::Coin;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::exit; use std::process::exit;
@@ -89,29 +87,21 @@ where
.duration_since(SystemTime::UNIX_EPOCH) .duration_since(SystemTime::UNIX_EPOCH)
.expect("the system clock is set to 01/01/1970 (or earlier)") .expect("the system clock is set to 01/01/1970 (or earlier)")
.as_secs(); .as_secs();
if epoch.state.is_final() { if epoch.state.is_final() {
if let Some(finish_timestamp) = epoch.finish_timestamp { if current_timestamp_secs + SAFETY_BUFFER_SECS >= epoch.finish_timestamp.seconds() {
if current_timestamp_secs + SAFETY_BUFFER_SECS >= finish_timestamp.seconds() { info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60);
info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60); exit(0);
exit(0);
}
} }
break; break;
} else if let Some(final_timestamp) = epoch.final_timestamp_secs() { } else {
// Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries // Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries
let secs_until_final = final_timestamp.saturating_sub(current_timestamp_secs) + 1; let secs_until_final = epoch
.final_timestamp_secs()
.saturating_sub(current_timestamp_secs)
+ 1;
info!("Approximately {} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.", secs_until_final); info!("Approximately {} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.", secs_until_final);
tokio::time::sleep(Duration::from_secs(secs_until_final)).await; tokio::time::sleep(Duration::from_secs(secs_until_final)).await;
} else if matches!(epoch.state, EpochState::WaitingInitialisation) {
info!("dkg hasn't been initialised yet and it is not known when it will be. Going to check again later");
tokio::time::sleep(Duration::from_secs(60 * 5)).await;
} else {
// this should never be the case since the only case where final timestamp is unknown is when it's waiting for initialisation,
// but let's guard ourselves against future changes
info!("it is unknown when coconut will be come available. Going to check again later");
tokio::time::sleep(Duration::from_secs(60 * 5)).await;
} }
} }
+2 -4
View File
@@ -2,20 +2,18 @@
name = "nym-credentials" name = "nym-credentials"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] } bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
cosmrs = { workspace = true } cosmrs = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
log = { workspace = true } log = { workspace = true }
zeroize = { workspace = true }
# I guess temporarily until we get serde support in coconut up and running # I guess temporarily until we get serde support in coconut up and running
nym-coconut-interface = { path = "../coconut-interface" } nym-coconut-interface = { path = "../coconut-interface" }
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric"] } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric", "hashing"] }
nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false } nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
+51 -93
View File
@@ -13,60 +13,38 @@ use nym_coconut_interface::{
PrivateAttribute, PublicAttribute, Signature, VerificationKey, PrivateAttribute, PublicAttribute, Signature, VerificationKey,
}; };
use nym_crypto::asymmetric::{encryption, identity}; use nym_crypto::asymmetric::{encryption, identity};
use zeroize::{Zeroize, ZeroizeOnDrop};
use super::utils::prepare_credential_for_spending; use super::utils::prepare_credential_for_spending;
use crate::error::Error; use crate::error::Error;
#[derive(Zeroize, ZeroizeOnDrop)] pub const PUBLIC_ATTRIBUTES: u32 = 2;
pub const PRIVATE_ATTRIBUTES: u32 = 2;
pub const TOTAL_ATTRIBUTES: u32 = PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES;
pub struct BandwidthVoucher { pub struct BandwidthVoucher {
// private attributes // a random secret value generated by the client used for double-spending detection
/// a random secret value generated by the client used for double-spending detection
serial_number: PrivateAttribute, serial_number: PrivateAttribute,
// a random secret value generated by the client used to bind multiple credentials together
/// a random secret value generated by the client used to bind multiple credentials together
binding_number: PrivateAttribute, binding_number: PrivateAttribute,
// the value (e.g., bandwidth) encoded in this voucher
// public atttributes: voucher_value: PublicAttribute,
/// the plain text value (e.g., bandwidth) encoded in this voucher // the plain text value (e.g., bandwidth) encoded in this voucher
// TODO: in another PR change the value from `"1000"` to `"1000unym"`
voucher_value_plain: String, voucher_value_plain: String,
// a field with public information, e.g., type of voucher, interval etc.
/// the plain text information voucher_info: PublicAttribute,
// the plain text information
voucher_info_plain: String, voucher_info_plain: String,
// the hash of the deposit transaction
/// the precomputed value (e.g., bandwidth) encoded in this voucher
_voucher_value_prehashed: PublicAttribute,
/// the precomputed field with public information, e.g., type of voucher, interval etc.
_voucher_info_prehashed: PublicAttribute,
/// the hash of the deposit transaction
#[zeroize(skip)]
tx_hash: Hash, tx_hash: Hash,
// base58 encoded private key ensuring the depositer requested these attributes
/// base58 encoded private key ensuring the depositer requested these attributes
signing_key: identity::PrivateKey, signing_key: identity::PrivateKey,
// base58 encoded private key ensuring only this client receives the signature share
/// base58 encoded private key ensuring only this client receives the signature share encryption_key: encryption::PrivateKey,
unused_ed25519: encryption::PrivateKey,
pedersen_commitments_openings: Vec<Attribute>, pedersen_commitments_openings: Vec<Attribute>,
#[zeroize(skip)]
blind_sign_request: BlindSignRequest, blind_sign_request: BlindSignRequest,
} }
impl BandwidthVoucher { impl BandwidthVoucher {
pub const PUBLIC_ATTRIBUTES: u32 = 2;
pub const PRIVATE_ATTRIBUTES: u32 = 2;
pub const ENCODED_ATTRIBUTES: u32 = 4;
pub fn default_parameters() -> Parameters {
// safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero
Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap()
}
pub fn new( pub fn new(
params: &Parameters, params: &Parameters,
voucher_value: String, voucher_value: String,
@@ -79,26 +57,24 @@ impl BandwidthVoucher {
let binding_number = params.random_scalar(); let binding_number = params.random_scalar();
let voucher_value_plain = voucher_value.clone(); let voucher_value_plain = voucher_value.clone();
let voucher_info_plain = voucher_info.clone(); let voucher_info_plain = voucher_info.clone();
let voucher_value = hash_to_scalar(voucher_value.as_bytes());
let _voucher_value_prehashed = hash_to_scalar(voucher_value); let voucher_info = hash_to_scalar(voucher_info.as_bytes());
let _voucher_info_prehashed = hash_to_scalar(voucher_info);
let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign( let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign(
params, params,
&[&serial_number, &binding_number], &[serial_number, binding_number],
&[&_voucher_value_prehashed, &_voucher_info_prehashed], &[voucher_value, voucher_info],
) )
.unwrap(); .unwrap();
BandwidthVoucher { BandwidthVoucher {
serial_number, serial_number,
binding_number, binding_number,
_voucher_value_prehashed, voucher_value,
voucher_value_plain, voucher_value_plain,
_voucher_info_prehashed, voucher_info,
voucher_info_plain, voucher_info_plain,
tx_hash, tx_hash,
signing_key, signing_key,
unused_ed25519: encryption_key, encryption_key,
pedersen_commitments_openings, pedersen_commitments_openings,
blind_sign_request, blind_sign_request,
} }
@@ -111,7 +87,7 @@ impl BandwidthVoucher {
let voucher_info_plain_b = self.voucher_info_plain.as_bytes(); let voucher_info_plain_b = self.voucher_info_plain.as_bytes();
let tx_hash_b = self.tx_hash.as_bytes(); let tx_hash_b = self.tx_hash.as_bytes();
let signing_key_b = self.signing_key.to_bytes(); let signing_key_b = self.signing_key.to_bytes();
let encryption_key_b = self.unused_ed25519.to_bytes(); let encryption_key_b = self.encryption_key.to_bytes();
let blind_sign_request_b = self.blind_sign_request.to_bytes(); let blind_sign_request_b = self.blind_sign_request.to_bytes();
let mut ret = Vec::new(); let mut ret = Vec::new();
@@ -195,13 +171,13 @@ impl BandwidthVoucher {
bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(), bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(),
) )
.or_else(utf_err)?; .or_else(utf_err)?;
let _voucher_value_prehashed = hash_to_scalar(&voucher_value_plain); let voucher_value = hash_to_scalar(&voucher_value_plain);
var_length_pointer += voucher_value_plain_no; var_length_pointer += voucher_value_plain_no;
let voucher_info_plain = String::from_utf8( let voucher_info_plain = String::from_utf8(
bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(), bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(),
) )
.or_else(utf_err)?; .or_else(utf_err)?;
let _voucher_info_prehashed = hash_to_scalar(&voucher_info_plain); let voucher_info = hash_to_scalar(&voucher_info_plain);
var_length_pointer += voucher_info_plain_no; var_length_pointer += voucher_info_plain_no;
let blind_sign_request = BlindSignRequest::from_bytes( let blind_sign_request = BlindSignRequest::from_bytes(
&bytes[var_length_pointer..var_length_pointer + blind_sign_request_no], &bytes[var_length_pointer..var_length_pointer + blind_sign_request_no],
@@ -220,43 +196,36 @@ impl BandwidthVoucher {
Ok(Self { Ok(Self {
serial_number, serial_number,
binding_number, binding_number,
_voucher_value_prehashed, voucher_value,
voucher_value_plain, voucher_value_plain,
_voucher_info_prehashed, voucher_info,
voucher_info_plain, voucher_info_plain,
tx_hash, tx_hash,
signing_key, signing_key,
unused_ed25519: encryption_key, encryption_key,
pedersen_commitments_openings, pedersen_commitments_openings,
blind_sign_request, blind_sign_request,
}) })
} }
/// Check if the plain values correspond to the PublicAttributes /// Check if the plain values correspond to the PublicAttributes
pub fn verify_against_plain(values: &[&PublicAttribute], plain_values: &[String]) -> bool { pub fn verify_against_plain(values: &[PublicAttribute], plain_values: &[String]) -> bool {
values.len() == 2 values.len() == 2
&& plain_values.len() == 2 && plain_values.len() == 2
&& values[0] == &hash_to_scalar(&plain_values[0]) && values[0] == hash_to_scalar(&plain_values[0])
&& values[1] == &hash_to_scalar(&plain_values[1]) && values[1] == hash_to_scalar(&plain_values[1])
} }
pub fn tx_hash(&self) -> Hash { pub fn tx_hash(&self) -> &Hash {
self.tx_hash &self.tx_hash
} }
pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> { pub fn get_public_attributes(&self) -> Vec<PublicAttribute> {
vec![ vec![self.voucher_value, self.voucher_info]
&self._voucher_value_prehashed,
&self._voucher_info_prehashed,
]
}
pub fn identity_key(&self) -> &identity::PrivateKey {
&self.signing_key
} }
pub fn encryption_key(&self) -> &encryption::PrivateKey { pub fn encryption_key(&self) -> &encryption::PrivateKey {
&self.unused_ed25519 &self.encryption_key
} }
pub fn pedersen_commitments_openings(&self) -> &Vec<Attribute> { pub fn pedersen_commitments_openings(&self) -> &Vec<Attribute> {
@@ -278,32 +247,27 @@ impl BandwidthVoucher {
] ]
} }
pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> { pub fn get_private_attributes(&self) -> Vec<PrivateAttribute> {
vec![&self.serial_number, &self.binding_number] vec![self.serial_number, self.binding_number]
} }
pub fn signable_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec<u8> { pub fn sign(&self, request: &BlindSignRequest) -> identity::Signature {
let mut message = request.to_bytes(); let mut message = request.to_bytes();
message.extend_from_slice(tx_hash.as_bytes()); message.extend_from_slice(self.tx_hash.to_string().as_bytes());
message self.signing_key.sign(&message)
}
pub fn sign(&self) -> identity::Signature {
let message = Self::signable_plaintext(&self.blind_sign_request, self.tx_hash);
self.signing_key.sign(message)
} }
} }
pub fn prepare_for_spending( pub fn prepare_for_spending(
voucher_value: u64, voucher_value: u64,
voucher_info: String, voucher_info: String,
serial_number: &PrivateAttribute, serial_number: PrivateAttribute,
binding_number: &PrivateAttribute, binding_number: PrivateAttribute,
epoch_id: u64, epoch_id: u64,
signature: &Signature, signature: &Signature,
verification_key: &VerificationKey, verification_key: &VerificationKey,
) -> Result<Credential, Error> { ) -> Result<Credential, Error> {
let params = Parameters::new(BandwidthVoucher::ENCODED_ATTRIBUTES)?; let params = Parameters::new(TOTAL_ATTRIBUTES)?;
prepare_credential_for_spending( prepare_credential_for_spending(
&params, &params,
@@ -352,30 +316,24 @@ mod test {
let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap(); let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap();
assert_eq!(voucher.serial_number, deserialized_voucher.serial_number); assert_eq!(voucher.serial_number, deserialized_voucher.serial_number);
assert_eq!(voucher.binding_number, deserialized_voucher.binding_number); assert_eq!(voucher.binding_number, deserialized_voucher.binding_number);
assert_eq!(voucher.voucher_value, deserialized_voucher.voucher_value);
assert_eq!( assert_eq!(
voucher.voucher_value_plain, voucher.voucher_value_plain,
deserialized_voucher.voucher_value_plain deserialized_voucher.voucher_value_plain
); );
assert_eq!(voucher.voucher_info, deserialized_voucher.voucher_info);
assert_eq!( assert_eq!(
voucher.voucher_info_plain, voucher.voucher_info_plain,
deserialized_voucher.voucher_info_plain deserialized_voucher.voucher_info_plain
); );
assert_eq!(
voucher._voucher_value_prehashed,
deserialized_voucher._voucher_value_prehashed
);
assert_eq!(
voucher._voucher_info_prehashed,
deserialized_voucher._voucher_info_prehashed
);
assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash); assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash);
assert_eq!( assert_eq!(
voucher.signing_key.to_string(), voucher.signing_key.to_string(),
deserialized_voucher.signing_key.to_string() deserialized_voucher.signing_key.to_string()
); );
assert_eq!( assert_eq!(
voucher.unused_ed25519.to_string(), voucher.encryption_key.to_string(),
deserialized_voucher.unused_ed25519.to_string() deserialized_voucher.encryption_key.to_string()
); );
assert_eq!( assert_eq!(
voucher.pedersen_commitments_openings, voucher.pedersen_commitments_openings,
@@ -413,11 +371,11 @@ mod test {
] ]
)); ));
assert!(!BandwidthVoucher::verify_against_plain( assert!(!BandwidthVoucher::verify_against_plain(
&[voucher.get_public_attributes()[0], &Attribute::one()], &[voucher.get_public_attributes()[0], Attribute::one()],
&voucher.get_public_attributes_plain() &voucher.get_public_attributes_plain()
)); ));
assert!(!BandwidthVoucher::verify_against_plain( assert!(!BandwidthVoucher::verify_against_plain(
&[&Attribute::one(), voucher.get_public_attributes()[1]], &[Attribute::one(), voucher.get_public_attributes()[1]],
&voucher.get_public_attributes_plain() &voucher.get_public_attributes_plain()
)); ));
assert!(BandwidthVoucher::verify_against_plain( assert!(BandwidthVoucher::verify_against_plain(
+1
View File
@@ -2,4 +2,5 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
pub mod bandwidth; pub mod bandwidth;
pub mod params;
pub mod utils; pub mod utils;
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_crypto::aes::Aes128;
use nym_crypto::blake3;
use nym_crypto::ctr;
type Aes128Ctr = ctr::Ctr64LE<Aes128>;
/// Hashing algorithm used during hkdf for ephemeral shared key generation per blinded signature
/// response encryption.
pub type NymApiCredentialHkdfAlgorithm = blake3::Hasher;
/// Encryption algorithm used for end-to-end encryption of blinded signature response
pub type NymApiCredentialEncryptionAlgorithm = Aes128Ctr;
+39 -22
View File
@@ -1,14 +1,18 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::coconut::bandwidth::BandwidthVoucher; use crate::coconut::bandwidth::{BandwidthVoucher, PRIVATE_ATTRIBUTES, PUBLIC_ATTRIBUTES};
use crate::coconut::params::{NymApiCredentialEncryptionAlgorithm, NymApiCredentialHkdfAlgorithm};
use crate::error::Error; use crate::error::Error;
use log::{debug, warn}; use log::{debug, warn};
use nym_api_requests::coconut::BlindSignRequestBody; use nym_api_requests::coconut::BlindSignRequestBody;
use nym_coconut_interface::{ use nym_coconut_interface::{
aggregate_signature_shares, aggregate_verification_keys, prove_bandwidth_credential, Attribute, aggregate_signature_shares, aggregate_verification_keys, prove_bandwidth_credential, Attribute,
Credential, Parameters, Signature, SignatureShare, VerificationKey, BlindedSignature, Credential, Parameters, Signature, SignatureShare, VerificationKey,
}; };
use nym_crypto::asymmetric::encryption::PublicKey;
use nym_crypto::shared_key::recompute_shared_key;
use nym_crypto::symmetric::stream_cipher;
use nym_validator_client::client::CoconutApiClient; use nym_validator_client::client::CoconutApiClient;
pub async fn obtain_aggregate_verification_key( pub async fn obtain_aggregate_verification_key(
@@ -32,34 +36,47 @@ pub async fn obtain_aggregate_verification_key(
async fn obtain_partial_credential( async fn obtain_partial_credential(
params: &Parameters, params: &Parameters,
voucher: &BandwidthVoucher, attributes: &BandwidthVoucher,
client: &nym_validator_client::client::NymApiClient, client: &nym_validator_client::client::NymApiClient,
validator_vk: &VerificationKey, validator_vk: &VerificationKey,
) -> Result<Signature, Error> { ) -> Result<Signature, Error> {
let public_attributes_plain = voucher.get_public_attributes_plain(); let public_attributes = attributes.get_public_attributes();
let blind_sign_request = voucher.blind_sign_request(); let public_attributes_plain = attributes.get_public_attributes_plain();
let request_signature = voucher.sign(); let private_attributes = attributes.get_private_attributes();
let blind_sign_request = attributes.blind_sign_request();
let blind_sign_request_body = BlindSignRequestBody::new( let blind_sign_request_body = BlindSignRequestBody::new(
blind_sign_request.clone(), blind_sign_request,
voucher.tx_hash(), attributes.tx_hash().to_string(),
request_signature, attributes.sign(blind_sign_request).to_base58_string(),
&public_attributes,
public_attributes_plain, public_attributes_plain,
(public_attributes.len() + private_attributes.len()) as u32,
); );
let response = client.blind_sign(&blind_sign_request_body).await?; let response = client.blind_sign(&blind_sign_request_body).await?;
let encrypted_signature = response.encrypted_signature;
let remote_key = PublicKey::from_bytes(&response.remote_key)?;
let blinded_signature = response.blinded_signature; let encryption_key = recompute_shared_key::<
NymApiCredentialEncryptionAlgorithm,
NymApiCredentialHkdfAlgorithm,
>(&remote_key, attributes.encryption_key());
let zero_iv = stream_cipher::zero_iv::<NymApiCredentialEncryptionAlgorithm>();
let blinded_signature_bytes = stream_cipher::decrypt::<NymApiCredentialEncryptionAlgorithm>(
&encryption_key,
&zero_iv,
&encrypted_signature,
);
let public_attributes = voucher.get_public_attributes(); let blinded_signature = BlindedSignature::from_bytes(&blinded_signature_bytes)?;
let private_attributes = voucher.get_private_attributes();
let unblinded_signature = blinded_signature.unblind_and_verify( let unblinded_signature = blinded_signature.unblind(
params, params,
validator_vk, validator_vk,
&private_attributes, &private_attributes,
&public_attributes, &public_attributes,
&blind_sign_request.get_commitment_hash(), &blind_sign_request.get_commitment_hash(),
voucher.pedersen_commitments_openings(), attributes.pedersen_commitments_openings(),
)?; )?;
Ok(unblinded_signature) Ok(unblinded_signature)
@@ -67,13 +84,16 @@ async fn obtain_partial_credential(
pub async fn obtain_aggregate_signature( pub async fn obtain_aggregate_signature(
params: &Parameters, params: &Parameters,
voucher: &BandwidthVoucher, attributes: &BandwidthVoucher,
coconut_api_clients: &[CoconutApiClient], coconut_api_clients: &[CoconutApiClient],
threshold: u64, threshold: u64,
) -> Result<Signature, Error> { ) -> Result<Signature, Error> {
if coconut_api_clients.is_empty() { if coconut_api_clients.is_empty() {
return Err(Error::NoValidatorsAvailable); return Err(Error::NoValidatorsAvailable);
} }
let public_attributes = attributes.get_public_attributes();
let private_attributes = attributes.get_private_attributes();
let mut shares = Vec::with_capacity(coconut_api_clients.len()); let mut shares = Vec::with_capacity(coconut_api_clients.len());
let validators_partial_vks: Vec<_> = coconut_api_clients let validators_partial_vks: Vec<_> = coconut_api_clients
.iter() .iter()
@@ -94,7 +114,7 @@ pub async fn obtain_aggregate_signature(
match obtain_partial_credential( match obtain_partial_credential(
params, params,
voucher, attributes,
&coconut_api_client.api_client, &coconut_api_client.api_client,
&coconut_api_client.verification_key, &coconut_api_client.verification_key,
) )
@@ -116,9 +136,6 @@ pub async fn obtain_aggregate_signature(
return Err(Error::NotEnoughShares); return Err(Error::NotEnoughShares);
} }
let public_attributes = voucher.get_public_attributes();
let private_attributes = voucher.get_private_attributes();
let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len()); let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len());
attributes.extend_from_slice(&private_attributes); attributes.extend_from_slice(&private_attributes);
attributes.extend_from_slice(&public_attributes); attributes.extend_from_slice(&public_attributes);
@@ -133,8 +150,8 @@ pub fn prepare_credential_for_spending(
params: &Parameters, params: &Parameters,
voucher_value: u64, voucher_value: u64,
voucher_info: String, voucher_info: String,
serial_number: &Attribute, serial_number: Attribute,
binding_number: &Attribute, binding_number: Attribute,
epoch_id: u64, epoch_id: u64,
signature: &Signature, signature: &Signature,
verification_key: &VerificationKey, verification_key: &VerificationKey,
@@ -148,7 +165,7 @@ pub fn prepare_credential_for_spending(
)?; )?;
Ok(Credential::new( Ok(Credential::new(
BandwidthVoucher::ENCODED_ATTRIBUTES, PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES,
theta, theta,
voucher_value, voucher_value,
voucher_info, voucher_info,
@@ -201,17 +201,6 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
} }
impl PrivateKey { impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let x25519_secret = x25519_dalek::StaticSecret::new(rng);
PrivateKey(x25519_secret)
}
pub fn public_key(&self) -> PublicKey {
self.into()
}
pub fn to_bytes(&self) -> [u8; PRIVATE_KEY_SIZE] { pub fn to_bytes(&self) -> [u8; PRIVATE_KEY_SIZE] {
self.0.to_bytes() self.0.to_bytes()
} }
+3 -23
View File
@@ -5,14 +5,13 @@ pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
pub use ed25519_dalek::SignatureError; pub use ed25519_dalek::SignatureError;
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use std::str::FromStr; use std::str::FromStr;
use thiserror::Error; use thiserror::Error;
use zeroize::{Zeroize, ZeroizeOnDrop}; use zeroize::{Zeroize, ZeroizeOnDrop};
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@@ -225,17 +224,6 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
} }
impl PrivateKey { impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_secret = ed25519_dalek::SecretKey::generate(rng);
PrivateKey(ed25519_secret)
}
pub fn public_key(&self) -> PublicKey {
self.into()
}
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] { pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0.to_bytes() self.0.to_bytes()
} }
@@ -307,7 +295,7 @@ impl PemStorableKey for PrivateKey {
} }
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug)]
pub struct Signature(ed25519_dalek::Signature); pub struct Signature(ed25519_dalek::Signature);
impl Signature { impl Signature {
@@ -331,14 +319,6 @@ impl Signature {
} }
} }
impl FromStr for Signature {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Signature::from_base58_string(s)
}
}
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
impl Serialize for Signature { impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+3 -4
View File
@@ -3,7 +3,6 @@ name = "nym-dkg"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
resolver = "2" resolver = "2"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -12,7 +11,7 @@ bitvec = "1.0.0"
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork # unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm # as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
bls12_381 = { workspace = true, default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] } bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="gt-serialisation", default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] }
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common", optional = true } nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common", optional = true }
bs58 = "0.4" bs58 = "0.4"
@@ -30,11 +29,11 @@ zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-pemstore = { path = "../pemstore" } nym-pemstore = { path = "../pemstore" }
[dependencies.group] [dependencies.group]
workspace = true version = "0.11"
default-features = false default-features = false
[dependencies.ff] [dependencies.ff]
workspace = true version = "0.11"
default-features = false default-features = false
[dev-dependencies] [dev-dependencies]
+2 -1
View File
@@ -14,7 +14,8 @@ use std::collections::HashMap;
use std::ops::Neg; use std::ops::Neg;
use zeroize::Zeroize; use zeroize::Zeroize;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct Ciphertexts { pub struct Ciphertexts {
pub rr: [G1Projective; NUM_CHUNKS], pub rr: [G1Projective; NUM_CHUNKS],
pub ss: [G1Projective; NUM_CHUNKS], pub ss: [G1Projective; NUM_CHUNKS],
+2 -1
View File
@@ -53,7 +53,8 @@ impl PublicKey {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct PublicKeyWithProof { pub struct PublicKeyWithProof {
pub(crate) key: PublicKey, pub(crate) key: PublicKey,
pub(crate) proof: ProofOfDiscreteLog, pub(crate) proof: ProofOfDiscreteLog,
+2 -1
View File
@@ -67,7 +67,8 @@ impl<'a> Instance<'a> {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct ProofOfChunking { pub struct ProofOfChunking {
y0: G1Projective, y0: G1Projective,
bb: Vec<G1Projective>, bb: Vec<G1Projective>,
+2 -1
View File
@@ -13,7 +13,8 @@ use zeroize::Zeroize;
const DISCRETE_LOG_DOMAIN: &[u8] = const DISCRETE_LOG_DOMAIN: &[u8] =
b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG"; b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG";
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct ProofOfDiscreteLog { pub struct ProofOfDiscreteLog {
pub(crate) rand_commitment: G1Projective, pub(crate) rand_commitment: G1Projective,
pub(crate) response: Scalar, pub(crate) response: Scalar,
+2 -1
View File
@@ -76,7 +76,8 @@ impl<'a> Instance<'a> {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct ProofOfSecretSharing { pub struct ProofOfSecretSharing {
ff: G1Projective, ff: G1Projective,
aa: G2Projective, aa: G2Projective,
+20 -100
View File
@@ -82,7 +82,8 @@ impl RecoveredVerificationKeys {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct Dealing { pub struct Dealing {
pub public_coefficients: PublicCoefficients, pub public_coefficients: PublicCoefficients,
pub ciphertexts: Ciphertexts, pub ciphertexts: Ciphertexts,
@@ -320,17 +321,9 @@ impl<'a> TryFrom<&'a nym_contracts_common::dealings::ContractSafeBytes> for Deal
} }
} }
/// Attempt to run the `VkCombine` algorithm to obtain the public master verification key, `VK` // this assumes all dealings have been verified
/// alongside shares of the verification key, `shvk_{1}`, `shvk_{2}`, ... `svhk_{n}`, where n is the number of receivers.
///
/// # Arguments
///
/// * `dealings`: map of dealer indices to dealings they generated
/// * `threshold`: explicit threshold value of the associated dealings
/// * `receivers`:map of receiver indices to their public keys
// note: this function assumes all dealings have already been verified
pub fn try_recover_verification_keys( pub fn try_recover_verification_keys(
dealings: &BTreeMap<NodeIndex, Dealing>, dealings: &[Dealing],
threshold: Threshold, threshold: Threshold,
receivers: &BTreeMap<NodeIndex, PublicKey>, receivers: &BTreeMap<NodeIndex, PublicKey>,
) -> Result<RecoveredVerificationKeys, DkgError> { ) -> Result<RecoveredVerificationKeys, DkgError> {
@@ -338,31 +331,24 @@ pub fn try_recover_verification_keys(
return Err(DkgError::NoDealingsAvailable); return Err(DkgError::NoDealingsAvailable);
} }
let threshold = threshold as usize; let threshold_usize = threshold as usize;
if dealings.len() < threshold {
return Err(DkgError::NotEnoughDealingsAvailable {
available: dealings.len(),
required: threshold,
});
}
if !dealings if !dealings
.values() .iter()
.all(|dealing| dealing.public_coefficients.size() == threshold) .all(|dealing| dealing.public_coefficients.size() == threshold_usize)
{ {
return Err(DkgError::MismatchedDealings); return Err(DkgError::MismatchedDealings);
} }
let dealer_indices = dealings.keys().collect::<Vec<_>>(); let indices = receivers.keys().collect::<Vec<_>>();
// Compute A0, ..., A_{t-1} // Compute A0, ..., A_{t-1}
let mut interpolated_coefficients = Vec::with_capacity(threshold); let mut interpolated_coefficients = Vec::with_capacity(threshold_usize);
for k in 0..threshold { for k in 0..threshold_usize {
let mut samples = Vec::with_capacity(dealer_indices.len()); let mut samples = Vec::with_capacity(indices.len());
for (dealer_index, dealing) in dealings.iter() { for (j, dealing) in dealings.iter().enumerate() {
samples.push(( samples.push((
Scalar::from(*dealer_index), Scalar::from(*indices[j]),
*dealing.public_coefficients.nth(k), *dealing.public_coefficients.nth(k),
)) ))
} }
@@ -379,7 +365,7 @@ pub fn try_recover_verification_keys(
// shvk_j = A0^{j^0} * A1^{j^1} * ... * A_{t-1}^{j^{t-1}} // shvk_j = A0^{j^0} * A1^{j^1} * ... * A_{t-1}^{j^{t-1}}
let verification_key_shares = receivers let verification_key_shares = receivers
.keys() .keys()
.map(|receiver_index| interpolated_coefficients.evaluate_at(&Scalar::from(*receiver_index))) .map(|index| interpolated_coefficients.evaluate_at(&Scalar::from(*index)))
.collect(); .collect();
Ok(RecoveredVerificationKeys { Ok(RecoveredVerificationKeys {
@@ -471,17 +457,14 @@ mod tests {
let dealings = node_indices let dealings = node_indices
.iter() .iter()
.map(|&dealer_index| { .map(|&dealer_index| {
( Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
let mut derived_secrets = Vec::new(); let mut derived_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = dealings let shares = dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
derived_secrets.push( derived_secrets.push(
@@ -530,12 +513,9 @@ mod tests {
let dealings = node_indices let dealings = node_indices
.iter() .iter()
.map(|&dealer_index| { .map(|&dealer_index| {
( Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
let RecoveredVerificationKeys { let RecoveredVerificationKeys {
recovered_master, recovered_master,
@@ -551,66 +531,6 @@ mod tests {
.is_ok()) .is_ok())
} }
#[test]
#[ignore] // expensive test
fn verifying_partial_verification_keys_with_different_dealers_and_receivers() {
let dummy_seed = [42u8; 32];
let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed);
let params = setup();
let dealer_indices = [1, 2, 3, 8];
let receiver_indices = [3, 4, 5, 6, 7];
let threshold = 3;
let mut receivers = BTreeMap::new();
let mut full_keys = Vec::new();
for index in &receiver_indices {
let (dk, pk) = keygen(&params, &mut rng);
receivers.insert(*index, *pk.public_key());
full_keys.push((dk, pk))
}
let dealings = dealer_indices
.iter()
.map(|&dealer_index| {
(
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
})
.collect::<BTreeMap<_, _>>();
let RecoveredVerificationKeys {
recovered_master,
recovered_partials,
} = try_recover_verification_keys(&dealings, threshold, &receivers).unwrap();
let g2 = G2Projective::generator();
let mut derived_secrets = Vec::new();
for (i, (dk, _)) in full_keys.iter().enumerate() {
let shares = dealings
.values()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect();
let recovered_secret = combine_shares(shares, &dealer_indices).unwrap();
// make sure it matches the associated vk
assert_eq!(recovered_partials[i], g2 * recovered_secret);
derived_secrets.push(recovered_secret)
}
assert!(verify_verification_keys(
&recovered_master,
&recovered_partials,
&receivers,
threshold
)
.is_ok())
}
#[test] #[test]
#[ignore] // expensive test #[ignore] // expensive test
fn dealing_roundtrip() { fn dealing_roundtrip() {
+1 -1
View File
@@ -3,7 +3,7 @@
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error, Clone)] #[derive(Debug, Error)]
pub enum DkgError { pub enum DkgError {
#[error("Provided set of values contained duplicate coordinate")] #[error("Provided set of values contained duplicate coordinate")]
DuplicateCoordinate, DuplicateCoordinate,
-1
View File
@@ -13,7 +13,6 @@ pub mod dealing;
pub(crate) mod share; pub(crate) mod share;
pub(crate) mod utils; pub(crate) mod utils;
pub use bls12_381::{G2Projective, Scalar};
pub use dealing::*; pub use dealing::*;
pub use share::*; pub use share::*;
+36 -51
View File
@@ -52,7 +52,7 @@ fn single_sender() {
.unwrap(); .unwrap();
// make sure each share is actually decryptable (even though proofs say they must be, perform this sanity check) // make sure each share is actually decryptable (even though proofs say they must be, perform this sanity check)
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let _recovered = decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap(); let _recovered = decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap();
} }
@@ -91,13 +91,10 @@ fn full_threshold_secret_sharing() {
let dealings = node_indices let dealings = node_indices
.iter() .iter()
.map(|&dealer_index| { .map(|&dealer_index| {
( Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
for dealing in dealings.values() { for dealing in dealings.iter() {
dealing dealing
.verify(&params, threshold, &receivers, None) .verify(&params, threshold, &receivers, None)
.unwrap(); .unwrap();
@@ -112,9 +109,9 @@ fn full_threshold_secret_sharing() {
let g2 = G2Projective::generator(); let g2 = G2Projective::generator();
let mut derived_secrets = Vec::new(); let mut derived_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = dealings let shares = dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
@@ -172,12 +169,9 @@ fn full_threshold_secret_resharing() {
let first_dealings = node_indices let first_dealings = node_indices
.iter() .iter()
.map(|&dealer_index| { .map(|&dealer_index| {
( Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
// recover verification keys // recover verification keys
let RecoveredVerificationKeys { let RecoveredVerificationKeys {
@@ -186,9 +180,9 @@ fn full_threshold_secret_resharing() {
} = try_recover_verification_keys(&first_dealings, threshold, &receivers).unwrap(); } = try_recover_verification_keys(&first_dealings, threshold, &receivers).unwrap();
let mut derived_secrets = Vec::new(); let mut derived_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = first_dealings let shares = first_dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
@@ -209,22 +203,19 @@ fn full_threshold_secret_resharing() {
.iter() .iter()
.zip(derived_secrets.iter()) .zip(derived_secrets.iter())
.map(|(&dealer_index, prior_secret)| { .map(|(&dealer_index, prior_secret)| {
( Dealing::create(
&mut rng,
&params,
dealer_index, dealer_index,
Dealing::create( threshold,
&mut rng, &receivers,
&params, Some(*prior_secret),
dealer_index,
threshold,
&receivers,
Some(*prior_secret),
)
.0,
) )
.0
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
for (reshared_dealing, prior_vk) in resharing_dealings.values().zip(recovered_partials.iter()) { for (reshared_dealing, prior_vk) in resharing_dealings.iter().zip(recovered_partials.iter()) {
reshared_dealing reshared_dealing
.verify(&params, threshold, &receivers, Some(*prior_vk)) .verify(&params, threshold, &receivers, Some(*prior_vk))
.unwrap(); .unwrap();
@@ -237,9 +228,9 @@ fn full_threshold_secret_resharing() {
} = try_recover_verification_keys(&resharing_dealings, threshold, &receivers).unwrap(); } = try_recover_verification_keys(&resharing_dealings, threshold, &receivers).unwrap();
let mut reshared_secrets = Vec::new(); let mut reshared_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = resharing_dealings let shares = resharing_dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
@@ -288,12 +279,9 @@ fn full_threshold_secret_resharing_left_party() {
let first_dealings = node_indices let first_dealings = node_indices
.iter() .iter()
.map(|&dealer_index| { .map(|&dealer_index| {
( Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0
dealer_index,
Dealing::create(&mut rng, &params, dealer_index, threshold, &receivers, None).0,
)
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
// recover verification keys // recover verification keys
let RecoveredVerificationKeys { let RecoveredVerificationKeys {
@@ -302,9 +290,9 @@ fn full_threshold_secret_resharing_left_party() {
} = try_recover_verification_keys(&first_dealings, threshold, &receivers).unwrap(); } = try_recover_verification_keys(&first_dealings, threshold, &receivers).unwrap();
let mut derived_secrets = Vec::new(); let mut derived_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = first_dealings let shares = first_dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
@@ -335,23 +323,20 @@ fn full_threshold_secret_resharing_left_party() {
.iter() .iter()
.zip(derived_secrets.iter().take(2)) .zip(derived_secrets.iter().take(2))
.map(|(&dealer_index, prior_secret)| { .map(|(&dealer_index, prior_secret)| {
( Dealing::create(
&mut rng,
&params,
dealer_index, dealer_index,
Dealing::create( threshold,
&mut rng, &receivers,
&params, Some(*prior_secret),
dealer_index,
threshold,
&receivers,
Some(*prior_secret),
)
.0,
) )
.0
}) })
.collect::<BTreeMap<_, _>>(); .collect::<Vec<_>>();
for (reshared_dealing, prior_vk) in resharing_dealings for (reshared_dealing, prior_vk) in resharing_dealings
.values() .iter()
.zip(recovered_partials.iter().take(2)) .zip(recovered_partials.iter().take(2))
{ {
reshared_dealing reshared_dealing
@@ -366,9 +351,9 @@ fn full_threshold_secret_resharing_left_party() {
} = try_recover_verification_keys(&resharing_dealings, threshold, &receivers).unwrap(); } = try_recover_verification_keys(&resharing_dealings, threshold, &receivers).unwrap();
let mut reshared_secrets = Vec::new(); let mut reshared_secrets = Vec::new();
for (i, (ref dk, _)) in full_keys.iter().enumerate() { for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
let shares = resharing_dealings let shares = resharing_dealings
.values() .iter()
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
.collect(); .collect();
-1
View File
@@ -2,7 +2,6 @@
name = "nym-execute" name = "nym-execute"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
[lib] [lib]
proc-macro = true proc-macro = true
-63
View File
@@ -81,15 +81,6 @@ ExitPolicy accept6 *6:119
ExitPolicy accept *4:120 ExitPolicy accept *4:120
ExitPolicy reject6 [FC00::]/7:* ExitPolicy reject6 [FC00::]/7:*
# Portless
ExitPolicy accept *:0
ExitPolicy accept *4:0
ExitPolicy accept *6:0
ExitPolicy reject *:0
ExitPolicy reject *4:0
ExitPolicy reject *6:0
#ExitPolicy accept *:8080 #and another comment here #ExitPolicy accept *:8080 #and another comment here
ExitPolicy reject FE80:0000:0000:0000:0202:B3FF:FE1E:8329:* ExitPolicy reject FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
@@ -193,60 +184,6 @@ ExitPolicy reject *:*
}, },
); );
// ExitPolicy accept *:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *4:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *6:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *4:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *6:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy FE80:0000:0000:0000:0202:B3FF:FE1E:8329:* // ExitPolicy FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
expected.push( expected.push(
Reject, Reject,
+14 -37
View File
@@ -264,13 +264,7 @@ mod stringified_ip_pattern {
impl AddressPortPattern { impl AddressPortPattern {
/// Return true iff this pattern matches a given address and port. /// Return true iff this pattern matches a given address and port.
pub fn matches(&self, addr: &IpAddr, port: u16) -> bool { pub fn matches(&self, addr: &IpAddr, port: u16) -> bool {
// For backward compatibility, we treat port 0 as a wildcard until all gateways have self.ip_pattern.matches(addr) && self.ports.contains(port)
// upgraded, at which point we can add *:0 to the policy list.
if port == 0 {
self.ip_pattern.matches(addr)
} else {
self.ip_pattern.matches(addr) && self.ports.contains(port)
}
} }
/// As matches, but accept a SocketAddr. /// As matches, but accept a SocketAddr.
@@ -401,9 +395,19 @@ fn parse_addr(s: &str) -> Result<IpAddr, PolicyError> {
}) })
} }
/// Helper: try to parse a port making sure it's non-zero
fn parse_port(s: &str) -> Result<u16, PolicyError> { fn parse_port(s: &str) -> Result<u16, PolicyError> {
s.parse::<u16>() let port = s
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() }) .parse::<u16>()
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() })?;
if port == 0 {
Err(PolicyError::InvalidPort {
raw: port.to_string(),
})
} else {
Ok(port)
}
} }
impl FromStr for IpPattern { impl FromStr for IpPattern {
@@ -490,10 +494,6 @@ impl PortRange {
PortRange::new_unchecked(1, 65535) PortRange::new_unchecked(1, 65535)
} }
pub fn new_zero() -> Self {
PortRange { start: 0, end: 0 }
}
/// Create a new PortRange. /// Create a new PortRange.
/// ///
/// The Portrange contains all ports between `start` and `end` inclusive. /// The Portrange contains all ports between `start` and `end` inclusive.
@@ -574,7 +574,6 @@ mod test {
check("marzipan:80"); check("marzipan:80");
check("1.2.3.4:90-80"); check("1.2.3.4:90-80");
check("1.2.3.4:0-80");
check("1.2.3.4/100:8888"); check("1.2.3.4/100:8888");
check("[1.2.3.4]/16:80"); check("[1.2.3.4]/16:80");
check("[::1]/130:8888"); check("[::1]/130:8888");
@@ -613,22 +612,6 @@ mod test {
check("0.0.0.0/0:*", &["127.0.0.1:80"], &["[f00b::]:80"]); check("0.0.0.0/0:*", &["127.0.0.1:80"], &["[f00b::]:80"]);
check("[::]/0:*", &["[f00b::]:80"], &["127.0.0.1:80"]); check("[::]/0:*", &["[f00b::]:80"], &["127.0.0.1:80"]);
check(
"*:0",
&["1.2.3.4:0", "[::1]:0", "9.0.0.0:0"],
&["1.2.3.4:443", "[::1]:500", "9.0.0.0:80", "[::1]:80"],
);
check(
"*4:0",
&["1.2.3.4:0", "9.0.0.0:0"],
&["1.2.3.4:443", "9.0.0.0:80", "[::1]:0", "[::1]:80"],
);
check(
"*6:0",
&["[::1]:0"],
&["[::1]:80", "1.2.3.4:0", "1.2.3.4:443"],
);
} }
#[test] #[test]
@@ -637,7 +620,6 @@ mod test {
policy.push(AddressPolicyAction::Accept, "*:443".parse()?); policy.push(AddressPolicyAction::Accept, "*:443".parse()?);
policy.push(AddressPolicyAction::Accept, "[::1]:80".parse()?); policy.push(AddressPolicyAction::Accept, "[::1]:80".parse()?);
policy.push(AddressPolicyAction::Reject, "*:80".parse()?); policy.push(AddressPolicyAction::Reject, "*:80".parse()?);
policy.push(AddressPolicyAction::Accept, "*:0".parse()?);
let policy = policy; // drop mut let policy = policy; // drop mut
assert!(policy assert!(policy
@@ -658,9 +640,6 @@ mod test {
assert!(policy assert!(policy
.allows_sockaddr(&"127.0.0.1:66".parse().unwrap()) .allows_sockaddr(&"127.0.0.1:66".parse().unwrap())
.is_none()); .is_none());
assert!(policy
.allows_sockaddr(&"127.0.0.1:0".parse().unwrap())
.unwrap());
Ok(()) Ok(())
} }
@@ -693,6 +672,7 @@ mod test {
assert_eq!("*".parse::<PortRange>().unwrap(), PortRange::new_all()); assert_eq!("*".parse::<PortRange>().unwrap(), PortRange::new_all());
assert!("hello".parse::<PortRange>().is_err()); assert!("hello".parse::<PortRange>().is_err());
assert!("0".parse::<PortRange>().is_err());
assert!("65536".parse::<PortRange>().is_err()); assert!("65536".parse::<PortRange>().is_err());
assert!("65537".parse::<PortRange>().is_err()); assert!("65537".parse::<PortRange>().is_err());
assert!("1-2-3".parse::<PortRange>().is_err()); assert!("1-2-3".parse::<PortRange>().is_err());
@@ -700,9 +680,6 @@ mod test {
assert!("1-".parse::<PortRange>().is_err()); assert!("1-".parse::<PortRange>().is_err());
assert!("-2".parse::<PortRange>().is_err()); assert!("-2".parse::<PortRange>().is_err());
assert!("-".parse::<PortRange>().is_err()); assert!("-".parse::<PortRange>().is_err());
assert_eq!("0".parse::<PortRange>().unwrap(), PortRange::new_zero(),);
assert!("0-1".parse::<PortRange>().is_err());
} }
#[test] #[test]
+1 -2
View File
@@ -2,7 +2,6 @@
name = "ledger" name = "ledger"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,4 +10,4 @@ bip32 = "0.5.1"
k256 = { workspace = true } k256 = { workspace = true }
ledger-transport = "0.10.0" ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0" ledger-transport-hid = "0.10.0"
thiserror = { workspace = true } thiserror = { workspace = true }
+1 -2
View File
@@ -3,7 +3,6 @@ name = "nym-mixnode-common"
version = "0.1.0" version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -21,7 +20,7 @@ tokio = { version = "1.24.1", features = [
"net", "net",
"io-util", "io-util",
] } ] }
tokio-util = { workspace = true, features = ["codec"] } tokio-util = { version = "0.7.4", features = ["codec"] }
url = { workspace = true } url = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
+3 -3
View File
@@ -108,13 +108,13 @@ impl ConnectionHandler {
let reply_packet = match maybe_echo_packet { let reply_packet = match maybe_echo_packet {
Some(Ok(echo_packet)) => self.handle_echo_packet(echo_packet), Some(Ok(echo_packet)) => self.handle_echo_packet(echo_packet),
Some(Err(err)) => { Some(Err(err)) => {
debug!( error!(
"The socket connection got corrupted with error: {err}. Closing the socket", "The socket connection got corrupted with error: {err}. Closing the socket",
); );
return; return;
} }
None => { None => {
debug!("The socket connection got terminated by the remote!"); error!("The socket connection got terminated by the remote!");
return; return;
} }
}; };
@@ -125,7 +125,7 @@ impl ConnectionHandler {
.write_all(reply_packet.to_bytes().as_ref()) .write_all(reply_packet.to_bytes().as_ref())
.await .await
{ {
debug!( error!(
"Failed to write reply packet back to the sender - {}. Closing the socket on our end", "Failed to write reply packet back to the sender - {}. Closing the socket on our end",
err err
); );
+1 -13
View File
@@ -111,7 +111,6 @@ impl NymNetworkDetails {
.with_additional_validator_endpoint(ValidatorDetails::new( .with_additional_validator_endpoint(ValidatorDetails::new(
var(var_names::NYXD).expect("nyxd validator not set"), var(var_names::NYXD).expect("nyxd validator not set"),
Some(var(var_names::NYM_API).expect("nym api not set")), Some(var(var_names::NYM_API).expect("nym api not set")),
get_optional_env(var_names::NYXD_WEBSOCKET),
)) ))
.with_mixnet_contract(Some( .with_mixnet_contract(Some(
var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"), var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"),
@@ -341,9 +340,6 @@ impl DenomDetailsOwned {
pub struct ValidatorDetails { pub struct ValidatorDetails {
// it is assumed those values are always valid since they're being provided in our defaults file // it is assumed those values are always valid since they're being provided in our defaults file
pub nyxd_url: String, pub nyxd_url: String,
//
pub websocket_url: Option<String>,
// Right now api_url is optional as we are not running the api reliably on all validators // Right now api_url is optional as we are not running the api reliably on all validators
// however, later on it should be a mandatory field // however, later on it should be a mandatory field
pub api_url: Option<String>, pub api_url: Option<String>,
@@ -351,10 +347,9 @@ pub struct ValidatorDetails {
} }
impl ValidatorDetails { impl ValidatorDetails {
pub fn new<S: Into<String>>(nyxd_url: S, api_url: Option<S>, websocket_url: Option<S>) -> Self { pub fn new<S: Into<String>>(nyxd_url: S, api_url: Option<S>) -> Self {
ValidatorDetails { ValidatorDetails {
nyxd_url: nyxd_url.into(), nyxd_url: nyxd_url.into(),
websocket_url: websocket_url.map(Into::into),
api_url: api_url.map(Into::into), api_url: api_url.map(Into::into),
} }
} }
@@ -362,7 +357,6 @@ impl ValidatorDetails {
pub fn new_nyxd_only<S: Into<String>>(nyxd_url: S) -> Self { pub fn new_nyxd_only<S: Into<String>>(nyxd_url: S) -> Self {
ValidatorDetails { ValidatorDetails {
nyxd_url: nyxd_url.into(), nyxd_url: nyxd_url.into(),
websocket_url: None,
api_url: None, api_url: None,
} }
} }
@@ -378,12 +372,6 @@ impl ValidatorDetails {
.as_ref() .as_ref()
.map(|url| url.parse().expect("the provided api url is invalid!")) .map(|url| url.parse().expect("the provided api url is invalid!"))
} }
pub fn websocket_url(&self) -> Option<Url> {
self.websocket_url
.as_ref()
.map(|url| url.parse().expect("the provided websocket url is invalid!"))
}
} }
fn fix_deprecated_environmental_variables() { fn fix_deprecated_environmental_variables() {
+1 -15
View File
@@ -3,7 +3,6 @@
use crate::var_names; use crate::var_names;
use crate::{DenomDetails, ValidatorDetails}; use crate::{DenomDetails, ValidatorDetails};
use std::str::FromStr;
pub const NETWORK_NAME: &str = "mainnet"; pub const NETWORK_NAME: &str = "mainnet";
@@ -26,7 +25,6 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/"; pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
pub const NYXD_URL: &str = "https://rpc.nymtech.net"; pub const NYXD_URL: &str = "https://rpc.nymtech.net";
pub const NYM_API: &str = "https://validator.nymtech.net/api/"; 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 EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging // I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
@@ -34,11 +32,7 @@ pub const EXIT_POLICY_URL: &str =
"https://nymtech.net/.wellknown/network-requester/exit-policy.txt"; "https://nymtech.net/.wellknown/network-requester/exit-policy.txt";
pub(crate) fn validators() -> Vec<ValidatorDetails> { pub(crate) fn validators() -> Vec<ValidatorDetails> {
vec![ValidatorDetails::new( vec![ValidatorDetails::new(NYXD_URL, Some(NYM_API))]
NYXD_URL,
Some(NYM_API),
Some(NYXD_WS),
)]
} }
const DEFAULT_SUFFIX: &str = "_MAINNET_DEFAULT"; const DEFAULT_SUFFIX: &str = "_MAINNET_DEFAULT";
@@ -66,12 +60,6 @@ pub fn read_var_if_not_default(var: &str) -> Option<String> {
} }
} }
pub fn read_parsed_var_if_not_default<T: FromStr>(var: &str) -> Option<Result<T, T::Err>> {
read_var_if_not_default(var)
.as_deref()
.map(FromStr::from_str)
}
pub fn export_to_env() { pub fn export_to_env() {
set_var_to_default(var_names::CONFIGURED, "true"); set_var_to_default(var_names::CONFIGURED, "true");
set_var_to_default(var_names::NETWORK_NAME, NETWORK_NAME); set_var_to_default(var_names::NETWORK_NAME, NETWORK_NAME);
@@ -116,7 +104,6 @@ pub fn export_to_env() {
); );
set_var_to_default(var_names::NYXD, NYXD_URL); set_var_to_default(var_names::NYXD, NYXD_URL);
set_var_to_default(var_names::NYM_API, NYM_API); set_var_to_default(var_names::NYM_API, NYM_API);
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::EXPLORER_API, EXPLORER_API);
set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL); set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
} }
@@ -165,7 +152,6 @@ pub fn export_to_env_if_not_set() {
); );
set_var_conditionally_to_default(var_names::NYXD, NYXD_URL); set_var_conditionally_to_default(var_names::NYXD, NYXD_URL);
set_var_conditionally_to_default(var_names::NYM_API, NYM_API); set_var_conditionally_to_default(var_names::NYM_API, NYM_API);
set_var_conditionally_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
set_var_conditionally_to_default(var_names::EXPLORER_API, EXPLORER_API); set_var_conditionally_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_conditionally_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL); set_var_conditionally_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
} }
-1
View File
@@ -26,7 +26,6 @@ pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
pub const NAME_SERVICE_CONTRACT_ADDRESS: &str = "NAME_SERVICE_CONTRACT_ADDRESS"; pub const NAME_SERVICE_CONTRACT_ADDRESS: &str = "NAME_SERVICE_CONTRACT_ADDRESS";
pub const NYXD: &str = "NYXD"; pub const NYXD: &str = "NYXD";
pub const NYM_API: &str = "NYM_API"; pub const NYM_API: &str = "NYM_API";
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
pub const EXPLORER_API: &str = "EXPLORER_API"; pub const EXPLORER_API: &str = "EXPLORER_API";
pub const EXIT_POLICY_URL: &str = "EXIT_POLICY"; pub const EXIT_POLICY_URL: &str = "EXIT_POLICY";
-1
View File
@@ -2,7 +2,6 @@
name = "nym-node-tester-utils" name = "nym-node-tester-utils"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -3,7 +3,6 @@ name = "nym-nonexhaustive-delayqueue"
version = "0.1.0" version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+3 -7
View File
@@ -3,12 +3,11 @@ name = "nym-coconut"
version = "0.5.0" version = "0.5.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>", "Ania Piotrowska <ania@nymtech.net>"] authors = ["Jedrzej Stuczynski <andrew@nymtech.net>", "Ania Piotrowska <ania@nymtech.net>"]
edition = "2021" edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] } bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="gt-serialisation", default-features = false, features = ["pairings", "alloc", "experimental"] }
itertools = "0.10" itertools = "0.10"
digest = "0.9" digest = "0.9"
rand = "0.8" rand = "0.8"
@@ -17,17 +16,16 @@ serde = { workspace = true }
serde_derive = "1.0" serde_derive = "1.0"
bs58 = "0.4.0" bs58 = "0.4.0"
sha2 = "0.9" sha2 = "0.9"
zeroize = { workspace = true, optional = true }
nym-dkg = { path = "../dkg" } nym-dkg = { path = "../dkg" }
nym-pemstore = { path = "../pemstore" } nym-pemstore = { path = "../pemstore" }
[dependencies.ff] [dependencies.ff]
workspace = true version = "0.11"
default-features = false default-features = false
[dependencies.group] [dependencies.group]
workspace = true version = "0.11"
default-features = false default-features = false
[dev-dependencies] [dev-dependencies]
@@ -40,9 +38,7 @@ name = "benchmarks"
harness = false harness = false
[features] [features]
key-zeroize = ["zeroize", "bls12_381/zeroize"]
default = [] default = []
[target.'cfg(target_env = "wasm32-unknown-unknown")'.dependencies] [target.'cfg(target_env = "wasm32-unknown-unknown")'.dependencies]
getrandom = { version="0.2", features=["js"] } getrandom = { version="0.2", features=["js"] }
+14 -14
View File
@@ -7,7 +7,7 @@ use ff::Field;
use group::{Curve, Group}; use group::{Curve, Group};
use nym_coconut::{ use nym_coconut::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, prepare_blind_sign, aggregate_signature_shares, aggregate_verification_keys, blind_sign, prepare_blind_sign,
prove_bandwidth_credential, random_scalars_refs, setup, ttp_keygen, verify_credential, prove_bandwidth_credential, setup, ttp_keygen, verify_credential,
verify_partial_blind_signature, Attribute, BlindedSignature, Parameters, Signature, verify_partial_blind_signature, Attribute, BlindedSignature, Parameters, Signature,
SignatureShare, VerificationKey, SignatureShare, VerificationKey,
}; };
@@ -66,8 +66,8 @@ fn unblind_and_aggregate(
params: &Parameters, params: &Parameters,
blinded_signatures: &[BlindedSignature], blinded_signatures: &[BlindedSignature],
partial_verification_keys: &[VerificationKey], partial_verification_keys: &[VerificationKey],
private_attributes: &[&Attribute], private_attributes: &[Attribute],
public_attributes: &[&Attribute], public_attributes: &[Attribute],
commitment_hash: &G1Projective, commitment_hash: &G1Projective,
pedersen_commitments_openings: &[Scalar], pedersen_commitments_openings: &[Scalar],
verification_key: &VerificationKey, verification_key: &VerificationKey,
@@ -78,7 +78,7 @@ fn unblind_and_aggregate(
.zip(partial_verification_keys.iter()) .zip(partial_verification_keys.iter())
.map(|(signature, partial_verification_key)| { .map(|(signature, partial_verification_key)| {
signature signature
.unblind_and_verify( .unblind(
params, params,
partial_verification_key, partial_verification_key,
private_attributes, private_attributes,
@@ -171,10 +171,10 @@ fn bench_coconut(c: &mut Criterion) {
let params = setup(case.num_public_attrs + case.num_private_attrs).unwrap(); let params = setup(case.num_public_attrs + case.num_private_attrs).unwrap();
random_scalars_refs!(public_attributes, params, case.num_public_attrs as usize); let public_attributes = params.n_random_scalars(case.num_public_attrs as usize);
let serial_number = params.random_scalar(); let serial_number = params.random_scalar();
let binding_number = params.random_scalar(); let binding_number = params.random_scalar();
let private_attributes = vec![&serial_number, &binding_number]; let private_attributes = vec![serial_number, binding_number];
// The prepare blind sign is performed by the user // The prepare blind sign is performed by the user
let (pedersen_commitments_openings, blind_sign_request) = let (pedersen_commitments_openings, blind_sign_request) =
@@ -213,7 +213,7 @@ fn bench_coconut(c: &mut Criterion) {
b.iter(|| { b.iter(|| {
blind_sign( blind_sign(
&params, &params,
keypair.secret_key(), &keypair.secret_key(),
&blind_sign_request, &blind_sign_request,
&public_attributes, &public_attributes,
) )
@@ -228,7 +228,7 @@ fn bench_coconut(c: &mut Criterion) {
for keypair in coconut_keypairs.iter() { for keypair in coconut_keypairs.iter() {
let blinded_signature = blind_sign( let blinded_signature = blind_sign(
&params, &params,
keypair.secret_key(), &keypair.secret_key(),
&blind_sign_request, &blind_sign_request,
&public_attributes, &public_attributes,
) )
@@ -238,7 +238,7 @@ fn bench_coconut(c: &mut Criterion) {
let verification_keys: Vec<VerificationKey> = coconut_keypairs let verification_keys: Vec<VerificationKey> = coconut_keypairs
.iter() .iter()
.map(|keypair| keypair.verification_key().clone()) .map(|keypair| keypair.verification_key())
.collect(); .collect();
// verify a random partial blind signature // verify a random partial blind signature
@@ -255,7 +255,7 @@ fn bench_coconut(c: &mut Criterion) {
b.iter(|| { b.iter(|| {
verify_partial_blind_signature( verify_partial_blind_signature(
&params, &params,
blind_sign_request.get_private_attributes_pedersen_commitments(), &blind_sign_request,
&public_attributes, &public_attributes,
random_blind_signature, random_blind_signature,
partial_verification_key, partial_verification_key,
@@ -310,8 +310,8 @@ fn bench_coconut(c: &mut Criterion) {
&params, &params,
&aggr_verification_key, &aggr_verification_key,
&aggregated_signature, &aggregated_signature,
&serial_number, serial_number,
&binding_number, binding_number,
) )
.unwrap(); .unwrap();
@@ -329,8 +329,8 @@ fn bench_coconut(c: &mut Criterion) {
&params, &params,
&aggr_verification_key, &aggr_verification_key,
&aggregated_signature, &aggregated_signature,
&serial_number, serial_number,
&binding_number, binding_number,
) )
.unwrap() .unwrap()
}) })

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