Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/sdk coconut #3273

Merged
merged 17 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://

- nym-network-statistics properly handles signals ([#3209])
- add socks5 support for Rust SDK ([#3226], [#3255])
- add coconut bandwidth credential support for Rust SDK ([#3273])

[#3209]: https://github.com/nymtech/nym/issues/3209
[#3226]: https://github.com/nymtech/nym/pull/3226
[#3255]: https://github.com/nymtech/nym/pull/3255
[#3273]: https://github.com/nymtech/nym/pull/3273

## [v1.1.13] (2023-03-15)

Expand Down
50 changes: 30 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ members = [
"clients/native/websocket-requests",
"clients/socks5",
"common/async-file-watcher",
"common/bandwidth-controller",
"common/bin-common",
"common/client-core",
"common/client-libs/gateway-client",
Expand All @@ -38,7 +39,6 @@ members = [
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/service-provider-directory",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/mobile-storage",
"common/credential-storage",
"common/credentials",
"common/crypto",
Expand Down
6 changes: 1 addition & 5 deletions clients/credential/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bip39 = { workspace = true }
clap = { version = "4.0", features = ["cargo", "derive"] }
log = "0.4"
rand = "0.7.3"
serde = { workspace = true, features = ["derive"] }
thiserror = "1.0"
url = "2.2"
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime

nym-coconut-interface = { path = "../../common/coconut-interface" }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-config = { path = "../../common/config" }
nym-credentials = { path = "../../common/credentials" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
nym-bin-common = { path = "../../common/bin-common"}
nym-network-defaults = { path = "../../common/network-defaults" }
nym-pemstore = { path = "../../common/pemstore" }
Expand Down
96 changes: 8 additions & 88 deletions clients/credential/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,13 @@

use clap::{ArgGroup, Args, Subcommand};
use log::*;
use nym_bandwidth_controller::acquire::state::State;
use nym_bin_common::completions::ArgShell;
use nym_coconut_interface::{Base58, Parameters};
use nym_credential_storage::storage::Storage;
use nym_credential_storage::PersistentStorage;
use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use nym_credentials::coconut::utils::obtain_aggregate_signature;
use nym_crypto::asymmetric::{encryption, identity};
use nym_network_defaults::VOUCHER_INFO;
use nym_credential_storage::persistent_storage::PersistentStorage;
use nym_validator_client::nyxd::traits::DkgQueryClient;
use nym_validator_client::nyxd::tx::Hash;
use nym_validator_client::CoconutApiClient;
use rand::rngs::OsRng;
use std::str::FromStr;

use crate::client::Client;
use crate::error::{CredentialClientError, Result};
use crate::error::Result;
use crate::recovery_storage::RecoveryStorage;
use crate::state::{KeyPair, State};

#[derive(Subcommand)]
pub(crate) enum Command {
Expand All @@ -45,10 +34,6 @@ pub(crate) struct Run {
#[clap(long)]
pub(crate) client_home_directory: std::path::PathBuf,

/// The nyxd URL that should be used
#[clap(long)]
pub(crate) nyxd_url: String,

/// A mnemonic for the account that buys the credential
#[clap(long)]
pub(crate) mnemonic: String,
Expand All @@ -67,81 +52,16 @@ pub(crate) struct Run {
pub(crate) recovery_mode: bool,
}

pub(crate) async fn deposit(nyxd_url: &str, mnemonic: &str, amount: u64) -> Result<State> {
let mut rng = OsRng;
let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng));
let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng));
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();

let client = Client::new(nyxd_url, mnemonic);
let tx_hash = client
.deposit(
amount,
signing_keypair.public_key.clone(),
encryption_keypair.public_key.clone(),
None,
)
.await?;

let voucher = BandwidthVoucher::new(
&params,
amount.to_string(),
VOUCHER_INFO.to_string(),
Hash::from_str(&tx_hash).map_err(|_| CredentialClientError::InvalidTxHash)?,
identity::PrivateKey::from_base58_string(&signing_keypair.private_key)?,
encryption::PrivateKey::from_base58_string(&encryption_keypair.private_key)?,
);

let state = State { voucher, params };

Ok(state)
}

pub(crate) async fn get_credential<C: DkgQueryClient + Send + Sync>(
state: &State,
client: &C,
shared_storage: PersistentStorage,
) -> Result<()> {
let epoch_id = client.get_current_epoch().await?.epoch_id;
let threshold = client
.get_current_epoch_threshold()
.await?
.ok_or(CredentialClientError::NoThreshold)?;
let coconut_api_clients = CoconutApiClient::all_coconut_api_clients(client, epoch_id).await?;

let signature = obtain_aggregate_signature(
&state.params,
&state.voucher,
&coconut_api_clients,
threshold,
)
.await?;
info!("Signature: {:?}", signature.to_bs58());
shared_storage
.insert_coconut_credential(
state.voucher.get_voucher_value(),
VOUCHER_INFO.to_string(),
state.voucher.get_private_attributes()[0].to_bs58(),
state.voucher.get_private_attributes()[1].to_bs58(),
signature.to_bs58(),
epoch_id.to_string(),
)
.await?;

Ok(())
}

pub(crate) async fn recover_credentials<C: DkgQueryClient + Send + Sync>(
client: &C,
recovery_storage: &RecoveryStorage,
shared_storage: PersistentStorage,
shared_storage: &PersistentStorage,
) -> Result<()> {
for voucher in recovery_storage.unconsumed_vouchers()? {
let state = State {
voucher,
params: Parameters::new(TOTAL_ATTRIBUTES).unwrap(),
};
if let Err(e) = get_credential(&state, client, shared_storage.clone()).await {
let state = State::new(voucher);
if let Err(e) =
nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await
{
error!(
"Could not recover deposit {} due to {:?}, try again later",
state.voucher.tx_hash(),
Expand Down
17 changes: 3 additions & 14 deletions clients/credential/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use thiserror::Error;

use nym_credential_storage::error::StorageError;
use nym_credentials::error::Error as CredentialError;
use nym_crypto::asymmetric::encryption::KeyRecoveryError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
use nym_validator_client::nyxd::error::NyxdError;
use nym_validator_client::ValidatorClientError;

Expand All @@ -18,6 +16,9 @@ pub enum CredentialClientError {
#[error("IO error: {0}")]
IOError(#[from] std::io::Error),

#[error("Bandwidth controller error: {0}")]
BandwidthControllerError(#[from] nym_bandwidth_controller::error::BandwidthControllerError),

#[error("Nyxd error: {0}")]
Nyxd(#[from] NyxdError),

Expand All @@ -27,21 +28,9 @@ pub enum CredentialClientError {
#[error("Credential error: {0}")]
Credential(#[from] CredentialError),

#[error("The tx hash provided is not valid")]
InvalidTxHash,

#[error("Could not parse Ed25519 data")]
Ed25519ParseError(#[from] Ed25519RecoveryError),

#[error("Could not parse X25519 data")]
X25519ParseError(#[from] KeyRecoveryError),

#[error("Could not use shared storage")]
SharedStorageError(#[from] StorageError),

#[error("Could not get system time")]
SysTimeError(#[from] SystemTimeError),

#[error("Threshold not set yet")]
NoThreshold,
}
Loading