Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd05759405 |
@@ -2,26 +2,6 @@
|
||||
|
||||
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v1.1.3] (2022-12-13)
|
||||
|
||||
### Changed
|
||||
|
||||
- validator-api: can recover from shutdown during DKG process ([#1872])
|
||||
- clients: deduplicate gateway inititialization, part of work towards a rust-sdk
|
||||
- clients: keep all transmission lanes going at all times by making priority probabilistic
|
||||
|
||||
### Fixed
|
||||
|
||||
- network-requester: fix bug where websocket connection disconnect resulted in success error code
|
||||
- clients: fix a few panics handling the gateway-client
|
||||
- mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884])
|
||||
|
||||
[#1872]: https://github.com/nymtech/nym/pull/1872
|
||||
[#1884]: https://github.com/nymtech/nym/pull/1884
|
||||
|
||||
|
||||
## [v1.1.2]
|
||||
|
||||
### Changed
|
||||
|
||||
Generated
+27
-7
@@ -603,7 +603,6 @@ dependencies = [
|
||||
"pemstore",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sled",
|
||||
"tap",
|
||||
"task",
|
||||
@@ -2669,7 +2668,7 @@ checksum = "fe435806c197dfeaa5efcded5e623c4b8230fd28fdf1e91e7a86e40ef2acbf90"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"no-std-compat",
|
||||
"snafu",
|
||||
"snafu 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3373,7 +3372,7 @@ dependencies = [
|
||||
"proxy-helpers",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"snafu 0.6.10",
|
||||
"socks5-requests",
|
||||
"tap",
|
||||
"task",
|
||||
@@ -5006,9 +5005,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.89"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
dependencies = [
|
||||
"itoa 1.0.1",
|
||||
"ryu",
|
||||
@@ -5196,6 +5195,16 @@ version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"snafu-derive 0.6.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
version = "0.7.1"
|
||||
@@ -5203,7 +5212,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5177903bf45656592d9eb5c0e22f408fc023aae51dbe2088889b71633ba451f2"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"snafu-derive",
|
||||
"snafu-derive 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu-derive"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6517,7 +6537,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "vesting-contract"
|
||||
version = "1.1.2"
|
||||
version = "1.1.0"
|
||||
dependencies = [
|
||||
"contracts-common",
|
||||
"cosmwasm-std",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "client-core"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -13,12 +13,11 @@ humantime-serde = "1.0"
|
||||
log = "0.4"
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.89"
|
||||
sled = { version = "0.34", optional = true }
|
||||
tap = "1.0.1"
|
||||
thiserror = "1.0.34"
|
||||
tokio = { version = "1.21.2", features = ["time", "macros"]}
|
||||
url = { version ="2.2", features = ["serde"] }
|
||||
tokio = { version = "1.21.2", features = ["time", "macros"]}
|
||||
|
||||
# internal
|
||||
config = { path = "../../common/config" }
|
||||
|
||||
@@ -23,11 +23,12 @@ use gateway_client::{
|
||||
AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver,
|
||||
MixnetMessageSender,
|
||||
};
|
||||
use log::{debug, info};
|
||||
use log::info;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use nymsphinx::addressing::nodes::NodeIdentity;
|
||||
#[cfg(feature = "reply-surb")]
|
||||
use std::path::PathBuf;
|
||||
#[cfg(feature = "reply-surb")]
|
||||
use tap::TapFallible;
|
||||
use task::{ShutdownListener, ShutdownNotifier};
|
||||
use url::Url;
|
||||
@@ -235,22 +236,22 @@ impl<'a> BaseClientBuilder<'a> {
|
||||
mixnet_message_sender: MixnetMessageSender,
|
||||
ack_sender: AcknowledgementSender,
|
||||
shutdown: ShutdownListener,
|
||||
) -> Result<GatewayClient, ClientCoreError> {
|
||||
) -> GatewayClient {
|
||||
let gateway_id = self.gateway_config.gateway_id.clone();
|
||||
if gateway_id.is_empty() {
|
||||
return Err(ClientCoreError::GatewayIdUnknown);
|
||||
panic!("The identity of the gateway is unknown - did you run `nym-client` init?")
|
||||
}
|
||||
let gateway_owner = self.gateway_config.gateway_owner.clone();
|
||||
if gateway_owner.is_empty() {
|
||||
return Err(ClientCoreError::GatewayOwnerUnknown);
|
||||
panic!("The owner of the gateway is unknown - did you run `nym-client` init?")
|
||||
}
|
||||
let gateway_address = self.gateway_config.gateway_listener.clone();
|
||||
if gateway_address.is_empty() {
|
||||
return Err(ClientCoreError::GatwayAddressUnknown);
|
||||
panic!("The address of the gateway is unknown - did you run `nym-client` init?")
|
||||
}
|
||||
|
||||
let gateway_identity = identity::PublicKey::from_base58_string(gateway_id)
|
||||
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
||||
.expect("provided gateway id is invalid!");
|
||||
|
||||
// disgusting wasm workaround since there's no key persistence there (nor `client init`)
|
||||
let shared_key = if self.key_manager.gateway_key_set() {
|
||||
@@ -277,10 +278,9 @@ impl<'a> BaseClientBuilder<'a> {
|
||||
gateway_client
|
||||
.authenticate_and_start()
|
||||
.await
|
||||
.tap_err(|err| {
|
||||
log::error!("Could not authenticate and start up the gateway connection - {err}")
|
||||
})?;
|
||||
Ok(gateway_client)
|
||||
.expect("could not authenticate and start up the gateway connection");
|
||||
|
||||
gateway_client
|
||||
}
|
||||
|
||||
// future responsible for periodically polling directory server and updating
|
||||
@@ -375,7 +375,7 @@ impl<'a> BaseClientBuilder<'a> {
|
||||
|
||||
let gateway_client = self
|
||||
.start_gateway_client(mixnet_messages_sender, ack_sender, shutdown.subscribe())
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
// The sphinx_message_sender is the transmitter for any component generating sphinx packets
|
||||
// that are to be sent to the mixnet. They are used by cover traffic stream and real
|
||||
@@ -412,8 +412,8 @@ impl<'a> BaseClientBuilder<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
debug!("Core client startup finished!");
|
||||
debug!("The address of this client is: {}", self.as_mix_recipient());
|
||||
info!("Client startup finished!");
|
||||
info!("The address of this client is: {}", self.as_mix_recipient());
|
||||
|
||||
Ok(BaseClient {
|
||||
client_input: ClientInputStatus::AwaitingProducer {
|
||||
|
||||
@@ -191,7 +191,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
// However it's still useful to alert the user that the gateway or the link to
|
||||
// the gateway can't keep up. Either due to insufficient bandwidth on the
|
||||
// client side, or that the gateway is overloaded.
|
||||
log::warn!("Failed to send sphinx packet - gateway or connection to gatway can't keep up");
|
||||
log::warn!("Failed to send: gateway appears to not keep up");
|
||||
}
|
||||
TrySendError::Closed(_) => {
|
||||
log::warn!("Failed to send cover message - channel closed");
|
||||
|
||||
@@ -489,7 +489,7 @@ where
|
||||
fn log_status_infrequent(&self) {
|
||||
if self.sending_delay_controller.current_multiplier() > 1 {
|
||||
log::warn!(
|
||||
"Unable to send packets at the default rate - rate reduced by setting the delay multiplier set to: {}",
|
||||
"Unable to send packets fast enough - sending delay multiplier set to: {}",
|
||||
self.sending_delay_controller.current_multiplier()
|
||||
);
|
||||
}
|
||||
|
||||
+3
-9
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use client_connections::TransmissionLane;
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
use rand::seq::SliceRandom;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
time::Duration,
|
||||
@@ -116,15 +116,9 @@ impl TransmissionBuffer {
|
||||
lanes.choose(&mut rand::thread_rng()).copied()
|
||||
}
|
||||
|
||||
// 2/3 chance to pick from the old lanes
|
||||
fn pick_random_old_lane(&self) -> Option<TransmissionLane> {
|
||||
let rand = &mut rand::thread_rng();
|
||||
if rand.gen_ratio(2, 3) {
|
||||
let lanes = self.get_oldest_set();
|
||||
lanes.choose(rand).copied()
|
||||
} else {
|
||||
self.pick_random_lane().copied()
|
||||
}
|
||||
let lanes = self.get_oldest_set();
|
||||
lanes.choose(&mut rand::thread_rng()).copied()
|
||||
}
|
||||
|
||||
fn pop_front_from_lane(&mut self, lane: &TransmissionLane) -> Option<RealMessage> {
|
||||
|
||||
@@ -34,10 +34,6 @@ pub fn missing_string_value() -> String {
|
||||
MISSING_VALUE.to_string()
|
||||
}
|
||||
|
||||
pub trait ClientCoreConfigTrait {
|
||||
fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Config<T> {
|
||||
@@ -49,12 +45,6 @@ pub struct Config<T> {
|
||||
debug: DebugConfig,
|
||||
}
|
||||
|
||||
impl<T> ClientCoreConfigTrait for Config<T> {
|
||||
fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig {
|
||||
&self.client.gateway_endpoint
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Config<T> {
|
||||
pub fn new<S: Into<String>>(id: S) -> Self
|
||||
where
|
||||
@@ -230,6 +220,10 @@ impl<T> Config<T> {
|
||||
&self.client.gateway_endpoint
|
||||
}
|
||||
|
||||
pub fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig {
|
||||
&self.client.gateway_endpoint
|
||||
}
|
||||
|
||||
pub fn get_database_path(&self) -> PathBuf {
|
||||
self.client.database_path.clone()
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ pub enum ClientCoreError {
|
||||
NoGatewayWithId(String),
|
||||
#[error("No gateways on network")]
|
||||
NoGatewaysOnNetwork,
|
||||
#[error("Failed to setup gateway")]
|
||||
FailedToSetupGateway,
|
||||
#[error("List of validator apis is empty")]
|
||||
ListOfValidatorApisIsEmpty,
|
||||
#[error("Could not load existing gateway configuration: {0}")]
|
||||
@@ -35,16 +33,6 @@ pub enum ClientCoreError {
|
||||
#[error("The current network topology seem to be insufficient to route any packets through")]
|
||||
InsufficientNetworkTopology,
|
||||
|
||||
#[error("The gateway id is invalid - {0}")]
|
||||
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
||||
|
||||
#[error("The identity of the gateway is unknwown - did you run init?")]
|
||||
GatewayIdUnknown,
|
||||
#[error("The owner of the gateway is unknown - did you run init?")]
|
||||
GatewayOwnerUnknown,
|
||||
#[error("The address of the gateway is unknown - did you run init?")]
|
||||
GatwayAddressUnknown,
|
||||
|
||||
#[error("Unexpected exit")]
|
||||
UnexpectedExit,
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Collection of initialization steps used by client implementations
|
||||
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use rand::{rngs::OsRng, seq::SliceRandom, thread_rng};
|
||||
use tap::TapFallible;
|
||||
use url::Url;
|
||||
|
||||
use config::NymConfig;
|
||||
use crypto::asymmetric::identity;
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
use gateway_client::GatewayClient;
|
||||
use gateway_requests::registration::handshake::SharedKeys;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use nymsphinx::addressing::nodes::NodeIdentity;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use tap::TapFallible;
|
||||
use topology::{filter::VersionFilterable, gateway};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
client::key_manager::KeyManager,
|
||||
@@ -16,9 +24,9 @@ use crate::{
|
||||
error::ClientCoreError,
|
||||
};
|
||||
|
||||
pub(super) async fn query_gateway_details(
|
||||
pub async fn query_gateway_details(
|
||||
validator_servers: Vec<Url>,
|
||||
chosen_gateway_id: Option<String>,
|
||||
chosen_gateway_id: Option<&str>,
|
||||
) -> Result<gateway::Node, ClientCoreError> {
|
||||
let validator_api = validator_servers
|
||||
.choose(&mut thread_rng())
|
||||
@@ -51,6 +59,26 @@ pub(super) async fn query_gateway_details(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn register_with_gateway_and_store_keys<T>(
|
||||
gateway_details: gateway::Node,
|
||||
config: &Config<T>,
|
||||
) -> Result<(), ClientCoreError>
|
||||
where
|
||||
T: NymConfig,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
let mut key_manager = KeyManager::new(&mut rng);
|
||||
|
||||
let shared_keys =
|
||||
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await?;
|
||||
key_manager.insert_gateway_shared_key(shared_keys);
|
||||
|
||||
let pathfinder = ClientKeyPathfinder::new_from_config(config);
|
||||
Ok(key_manager
|
||||
.store_keys(&pathfinder)
|
||||
.tap_err(|err| log::error!("Failed to generate keys: {err}"))?)
|
||||
}
|
||||
|
||||
async fn register_with_gateway(
|
||||
gateway: &gateway::Node,
|
||||
our_identity: Arc<identity::KeyPair>,
|
||||
@@ -74,22 +102,46 @@ async fn register_with_gateway(
|
||||
Ok(shared_keys)
|
||||
}
|
||||
|
||||
pub(super) async fn register_with_gateway_and_store_keys<T>(
|
||||
gateway_details: gateway::Node,
|
||||
config: &Config<T>,
|
||||
) -> Result<(), ClientCoreError>
|
||||
pub fn show_address<T>(config: &Config<T>) -> Result<(), ClientCoreError>
|
||||
where
|
||||
T: NymConfig,
|
||||
T: config::NymConfig,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
let mut key_manager = KeyManager::new(&mut rng);
|
||||
fn load_identity_keys(
|
||||
pathfinder: &ClientKeyPathfinder,
|
||||
) -> Result<identity::KeyPair, ClientCoreError> {
|
||||
let identity_keypair: identity::KeyPair =
|
||||
pemstore::load_keypair(&pemstore::KeyPairPath::new(
|
||||
pathfinder.private_identity_key().to_owned(),
|
||||
pathfinder.public_identity_key().to_owned(),
|
||||
))
|
||||
.tap_err(|_| log::error!("Failed to read stored identity key files"))?;
|
||||
Ok(identity_keypair)
|
||||
}
|
||||
|
||||
let shared_keys =
|
||||
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await?;
|
||||
key_manager.insert_gateway_shared_key(shared_keys);
|
||||
fn load_sphinx_keys(
|
||||
pathfinder: &ClientKeyPathfinder,
|
||||
) -> Result<encryption::KeyPair, ClientCoreError> {
|
||||
let sphinx_keypair: encryption::KeyPair =
|
||||
pemstore::load_keypair(&pemstore::KeyPairPath::new(
|
||||
pathfinder.private_encryption_key().to_owned(),
|
||||
pathfinder.public_encryption_key().to_owned(),
|
||||
))
|
||||
.tap_err(|_| log::error!("Failed to read stored sphinx key files"))?;
|
||||
Ok(sphinx_keypair)
|
||||
}
|
||||
|
||||
let pathfinder = ClientKeyPathfinder::new_from_config(config);
|
||||
Ok(key_manager
|
||||
.store_keys(&pathfinder)
|
||||
.tap_err(|err| log::error!("Failed to generate keys: {err}"))?)
|
||||
let identity_keypair = load_identity_keys(&pathfinder)?;
|
||||
let sphinx_keypair = load_sphinx_keys(&pathfinder)?;
|
||||
|
||||
let client_recipient = Recipient::new(
|
||||
*identity_keypair.public_key(),
|
||||
*sphinx_keypair.public_key(),
|
||||
// TODO: below only works under assumption that gateway address == gateway id
|
||||
// (which currently is true)
|
||||
NodeIdentity::from_base58_string(config.get_gateway_id())?,
|
||||
);
|
||||
|
||||
println!("\nThe address of this client is: {}", client_recipient);
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Collection of initialization steps used by client implementations
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use nymsphinx::addressing::{clients::Recipient, nodes::NodeIdentity};
|
||||
use serde::Serialize;
|
||||
use tap::TapFallible;
|
||||
|
||||
use config::NymConfig;
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
|
||||
use crate::{
|
||||
config::{
|
||||
persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config,
|
||||
GatewayEndpointConfig,
|
||||
},
|
||||
error::ClientCoreError,
|
||||
init::helpers::{query_gateway_details, register_with_gateway_and_store_keys},
|
||||
};
|
||||
|
||||
mod helpers;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct InitResults {
|
||||
version: String,
|
||||
id: String,
|
||||
identity_key: String,
|
||||
encryption_key: String,
|
||||
gateway_id: String,
|
||||
gateway_listener: String,
|
||||
}
|
||||
|
||||
impl InitResults {
|
||||
pub fn new<T>(config: &Config<T>, address: &Recipient) -> Self
|
||||
where
|
||||
T: NymConfig,
|
||||
{
|
||||
Self {
|
||||
version: config.get_version().to_string(),
|
||||
id: config.get_id(),
|
||||
identity_key: address.identity().to_base58_string(),
|
||||
encryption_key: address.encryption_key().to_base58_string(),
|
||||
gateway_id: config.get_gateway_id(),
|
||||
gateway_listener: config.get_gateway_listener(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for InitResults {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "Version: {}", self.version)?;
|
||||
writeln!(f, "ID: {}", self.id)?;
|
||||
writeln!(f, "Identity key: {}", self.identity_key)?;
|
||||
writeln!(f, "Encryption: {}", self.encryption_key)?;
|
||||
writeln!(f, "Gateway ID: {}", self.gateway_id)?;
|
||||
write!(f, "Gateway: {}", self.gateway_listener)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience function for setting up the gateway for a client. Depending on the arguments given
|
||||
/// it will do the sensible thing.
|
||||
pub async fn setup_gateway<C: NymConfig + ClientCoreConfigTrait, T: NymConfig>(
|
||||
register_gateway: bool,
|
||||
user_chosen_gateway_id: Option<String>,
|
||||
config: &Config<T>,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
let id = config.get_id();
|
||||
if register_gateway {
|
||||
register_with_gateway(user_chosen_gateway_id, config).await
|
||||
} else if let Some(user_chosen_gateway_id) = user_chosen_gateway_id {
|
||||
config_gateway_with_existing_keys(user_chosen_gateway_id, config).await
|
||||
} else {
|
||||
reuse_existing_gateway_config::<C>(&id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the gateway details by querying the validator-api. Either pick one at random or use
|
||||
/// the chosen one if it's among the available ones.
|
||||
/// Saves keys to disk, specified by the paths in `config`.
|
||||
pub async fn register_with_gateway<T: NymConfig>(
|
||||
user_chosen_gateway_id: Option<String>,
|
||||
config: &Config<T>,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
println!("Configuring gateway");
|
||||
let gateway =
|
||||
query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id).await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
|
||||
// Registering with gateway by setting up and writing shared keys to disk
|
||||
log::trace!("Registering gateway");
|
||||
register_with_gateway_and_store_keys(gateway.clone(), config).await?;
|
||||
println!("Saved all generated keys");
|
||||
|
||||
Ok(gateway.into())
|
||||
}
|
||||
|
||||
/// Set the gateway using the usual procedue of querying the validator-api, but don't register or
|
||||
/// create any keys.
|
||||
/// This assumes that the user knows what they are doing, and that the existing keys are valid for
|
||||
/// the gateway being used
|
||||
pub async fn config_gateway_with_existing_keys<T: NymConfig>(
|
||||
user_chosen_gateway_id: String,
|
||||
config: &Config<T>,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
println!("Using gateway provided by user, keeping existing keys");
|
||||
let gateway = query_gateway_details(
|
||||
config.get_validator_api_endpoints(),
|
||||
Some(user_chosen_gateway_id),
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
Ok(gateway.into())
|
||||
}
|
||||
|
||||
/// Read and reuse the existing gateway configuration from a file that was generate earlier.
|
||||
pub fn reuse_existing_gateway_config<T: NymConfig + ClientCoreConfigTrait>(
|
||||
id: &str,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
println!("Not registering gateway, will reuse existing config and keys");
|
||||
T::load_from_file(Some(id))
|
||||
.map(|existing_config| existing_config.get_gateway_endpoint().clone())
|
||||
.map_err(|err| {
|
||||
log::error!(
|
||||
"Unable to configure gateway: {err}. \n
|
||||
Seems like the client was already initialized but it was not possible to read \
|
||||
the existing configuration file. \n
|
||||
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
|
||||
removing the existing configuration and starting over."
|
||||
);
|
||||
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the client address by loading the keys from stored files.
|
||||
pub fn get_client_address_from_stored_keys<T>(
|
||||
config: &Config<T>,
|
||||
) -> Result<Recipient, ClientCoreError>
|
||||
where
|
||||
T: config::NymConfig,
|
||||
{
|
||||
fn load_identity_keys(
|
||||
pathfinder: &ClientKeyPathfinder,
|
||||
) -> Result<identity::KeyPair, ClientCoreError> {
|
||||
let identity_keypair: identity::KeyPair =
|
||||
pemstore::load_keypair(&pemstore::KeyPairPath::new(
|
||||
pathfinder.private_identity_key().to_owned(),
|
||||
pathfinder.public_identity_key().to_owned(),
|
||||
))
|
||||
.tap_err(|_| log::error!("Failed to read stored identity key files"))?;
|
||||
Ok(identity_keypair)
|
||||
}
|
||||
|
||||
fn load_sphinx_keys(
|
||||
pathfinder: &ClientKeyPathfinder,
|
||||
) -> Result<encryption::KeyPair, ClientCoreError> {
|
||||
let sphinx_keypair: encryption::KeyPair =
|
||||
pemstore::load_keypair(&pemstore::KeyPairPath::new(
|
||||
pathfinder.private_encryption_key().to_owned(),
|
||||
pathfinder.public_encryption_key().to_owned(),
|
||||
))
|
||||
.tap_err(|_| log::error!("Failed to read stored sphinx key files"))?;
|
||||
Ok(sphinx_keypair)
|
||||
}
|
||||
|
||||
let pathfinder = ClientKeyPathfinder::new_from_config(config);
|
||||
let identity_keypair = load_identity_keys(&pathfinder)?;
|
||||
let sphinx_keypair = load_sphinx_keys(&pathfinder)?;
|
||||
|
||||
let client_recipient = Recipient::new(
|
||||
*identity_keypair.public_key(),
|
||||
*sphinx_keypair.public_key(),
|
||||
// TODO: below only works under assumption that gateway address == gateway id
|
||||
// (which currently is true)
|
||||
NodeIdentity::from_base58_string(config.get_gateway_id())?,
|
||||
);
|
||||
|
||||
Ok(client_recipient)
|
||||
}
|
||||
|
||||
pub fn output_to_json<T: Serialize>(init_results: &T, output_file: &str) {
|
||||
match std::fs::File::create(output_file) {
|
||||
Ok(file) => match serde_json::to_writer_pretty(file, init_results) {
|
||||
Ok(_) => println!("Saved: {}", output_file),
|
||||
Err(err) => eprintln!("Could not save {}: {}", output_file, err),
|
||||
},
|
||||
Err(err) => eprintln!("Could not save {}: {}", output_file, err),
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,6 @@ pub(crate) async fn get_credential(state: &State, shared_storage: PersistentStor
|
||||
&coconut_api_clients,
|
||||
)
|
||||
.await?;
|
||||
println!("Signature: {:?}", signature.to_bs58());
|
||||
shared_storage
|
||||
.insert_coconut_credential(
|
||||
state.amount.to_string(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
@@ -26,9 +26,7 @@ log = "0.4" # self explanatory
|
||||
pretty_env_logger = "0.4" # for formatting log messages
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
|
||||
serde = { version = "1.0.104", features = ["derive"] } # for config serialization/deserialization
|
||||
serde_json = "1.0"
|
||||
sled = "0.34" # for storage of replySURB decryption keys
|
||||
tap = "1.0.1"
|
||||
thiserror = "1.0.34"
|
||||
tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } # async runtime
|
||||
tokio-tungstenite = "0.14" # websocket
|
||||
@@ -53,6 +51,7 @@ topology = { path = "../../common/topology" }
|
||||
validator-client = { path = "../../common/client-libs/validator-client", features = ["nymd-client"] }
|
||||
version-checker = { path = "../../common/version-checker" }
|
||||
websocket-requests = { path = "websocket-requests" }
|
||||
tap = "1.0.1"
|
||||
|
||||
[features]
|
||||
coconut = ["coconut-interface", "credentials", "credentials/coconut", "gateway-requests/coconut", "gateway-client/coconut", "client-core/coconut"]
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::template::config_template;
|
||||
use client_core::config::Config as BaseConfig;
|
||||
pub use client_core::config::MISSING_VALUE;
|
||||
use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig};
|
||||
use config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
|
||||
use config::NymConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -28,7 +28,7 @@ impl SocketType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_websocket(self) -> bool {
|
||||
pub fn is_websocket(&self) -> bool {
|
||||
matches!(self, SocketType::WebSocket)
|
||||
}
|
||||
}
|
||||
@@ -73,12 +73,6 @@ impl NymConfig for Config {
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientCoreConfigTrait for Config {
|
||||
fn get_gateway_endpoint(&self) -> &client_core::config::GatewayEndpointConfig {
|
||||
self.base.get_gateway_endpoint()
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new<S: Into<String>>(id: S) -> Self {
|
||||
Config {
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use clap::Args;
|
||||
use client_core::{config::GatewayEndpointConfig, error::ClientCoreError};
|
||||
use config::NymConfig;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use serde::Serialize;
|
||||
use tap::TapFallible;
|
||||
|
||||
use crate::{
|
||||
client::config::Config,
|
||||
commands::{override_config, OverrideConfig},
|
||||
error::ClientError,
|
||||
};
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
@@ -60,10 +55,6 @@ pub(crate) struct Init {
|
||||
#[cfg(feature = "coconut")]
|
||||
#[clap(long)]
|
||||
enabled_credentials_mode: bool,
|
||||
|
||||
/// Save a summary of the initialization to a json file
|
||||
#[clap(long)]
|
||||
output_json: bool,
|
||||
}
|
||||
|
||||
impl From<Init> for OverrideConfig {
|
||||
@@ -82,30 +73,7 @@ impl From<Init> for OverrideConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct InitResults {
|
||||
#[serde(flatten)]
|
||||
client_core: client_core::init::InitResults,
|
||||
client_listening_port: String,
|
||||
}
|
||||
|
||||
impl InitResults {
|
||||
fn new(config: &Config, address: &Recipient) -> Self {
|
||||
Self {
|
||||
client_core: client_core::init::InitResults::new(config.get_base(), address),
|
||||
client_listening_port: config.get_listening_port().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for InitResults {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "{}", self.client_core)?;
|
||||
write!(f, "Client listening port: {}", self.client_listening_port)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
||||
pub(crate) async fn execute(args: &Init) {
|
||||
println!("Initialising client...");
|
||||
|
||||
let id = &args.id;
|
||||
@@ -129,44 +97,25 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
||||
let register_gateway = !already_init || user_wants_force_register;
|
||||
|
||||
// Attempt to use a user-provided gateway, if possible
|
||||
let user_chosen_gateway_id = args.gateway.clone();
|
||||
let user_chosen_gateway_id = args.gateway.as_deref();
|
||||
|
||||
// Load and potentially override config
|
||||
let mut config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
|
||||
|
||||
// Setup gateway by either registering a new one, or creating a new config from the selected
|
||||
// one but with keys kept, or reusing the gateway configuration.
|
||||
let gateway = client_core::init::setup_gateway::<Config, _>(
|
||||
register_gateway,
|
||||
user_chosen_gateway_id,
|
||||
config.get_base(),
|
||||
)
|
||||
.await
|
||||
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
||||
let mut config = Config::new(id);
|
||||
let override_config_fields = OverrideConfig::from(args.clone());
|
||||
config = override_config(config, override_config_fields);
|
||||
|
||||
let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config)
|
||||
.await
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Failed to setup gateway\nError: {err}");
|
||||
std::process::exit(1)
|
||||
});
|
||||
config.get_base_mut().with_gateway_endpoint(gateway);
|
||||
|
||||
config.save_to_file(None).tap_err(|_| {
|
||||
log::error!("Failed to save the config file");
|
||||
})?;
|
||||
|
||||
print_saved_config(&config);
|
||||
|
||||
let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?;
|
||||
let init_results = InitResults::new(&config, &address);
|
||||
println!("{}", init_results);
|
||||
|
||||
// Output summary to a json file, if specified
|
||||
if args.output_json {
|
||||
client_core::init::output_to_json(&init_results, "client_init_results.json");
|
||||
}
|
||||
|
||||
println!("\nThe address of this client is: {}\n", address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_saved_config(config: &Config) {
|
||||
let config_save_location = config.get_config_file_save_location();
|
||||
config
|
||||
.save_to_file(None)
|
||||
.expect("Failed to save the config file");
|
||||
|
||||
println!("Saved configuration file to {:?}", config_save_location);
|
||||
println!("Using gateway: {}", config.get_base().get_gateway_id());
|
||||
log::debug!("Gateway id: {}", config.get_base().get_gateway_id());
|
||||
@@ -175,5 +124,63 @@ fn print_saved_config(config: &Config) {
|
||||
"Gateway listener: {}",
|
||||
config.get_base().get_gateway_listener()
|
||||
);
|
||||
println!("Client configuration completed.\n");
|
||||
println!("Client configuration completed.");
|
||||
|
||||
client_core::init::show_address(config.get_base()).unwrap_or_else(|err| {
|
||||
eprintln!("Failed to show address\nError: {err}");
|
||||
std::process::exit(1)
|
||||
});
|
||||
}
|
||||
|
||||
async fn setup_gateway(
|
||||
id: &str,
|
||||
register: bool,
|
||||
user_chosen_gateway_id: Option<&str>,
|
||||
config: &Config,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
if register {
|
||||
// Get the gateway details by querying the validator-api. Either pick one at random or use
|
||||
// the chosen one if it's among the available ones.
|
||||
println!("Configuring gateway");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
|
||||
// Registering with gateway by setting up and writing shared keys to disk
|
||||
log::trace!("Registering gateway");
|
||||
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
|
||||
.await?;
|
||||
println!("Saved all generated keys");
|
||||
|
||||
Ok(gateway.into())
|
||||
} else if user_chosen_gateway_id.is_some() {
|
||||
// Just set the config, don't register or create any keys
|
||||
// This assumes that the user knows what they are doing, and that the existing keys are
|
||||
// valid for the gateway being used
|
||||
println!("Using gateway provided by user, keeping existing keys");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
Ok(gateway.into())
|
||||
} else {
|
||||
println!("Not registering gateway, will reuse existing config and keys");
|
||||
let existing_config = Config::load_from_file(Some(id)).map_err(|err| {
|
||||
log::error!(
|
||||
"Unable to configure gateway: {err}. \n
|
||||
Seems like the client was already initialized but it was not possible to read \
|
||||
the existing configuration file. \n
|
||||
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
|
||||
removing the existing configuration and starting over."
|
||||
);
|
||||
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
|
||||
})?;
|
||||
|
||||
Ok(existing_config.get_base().get_gateway_endpoint().clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), ClientError> {
|
||||
let bin_name = "nym-native-client";
|
||||
|
||||
match &args.command {
|
||||
Commands::Init(m) => init::execute(m).await?,
|
||||
Commands::Init(m) => init::execute(m).await,
|
||||
Commands::Run(m) => run::execute(m).await?,
|
||||
Commands::Upgrade(m) => upgrade::execute(m),
|
||||
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
|
||||
|
||||
@@ -2,8 +2,6 @@ use client_core::error::ClientCoreError;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum ClientError {
|
||||
#[error("I/O error: {0}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error("client-core error: {0}")]
|
||||
ClientCoreError(#[from] ClientCoreError),
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
@@ -19,8 +19,7 @@ pin-project = "1.0"
|
||||
pretty_env_logger = "0.4"
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
serde = { version = "1.0", features = ["derive"] } # for config serialization/deserialization
|
||||
serde_json = "1.0.89"
|
||||
tap = "1.0.1"
|
||||
snafu = "0.6"
|
||||
thiserror = "1.0.34"
|
||||
tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
|
||||
url = "2.2"
|
||||
@@ -47,6 +46,7 @@ task = { path = "../../common/task" }
|
||||
topology = { path = "../../common/topology" }
|
||||
validator-client = { path = "../../common/client-libs/validator-client", features = ["nymd-client"] }
|
||||
version-checker = { path = "../../common/version-checker" }
|
||||
tap = "1.0.1"
|
||||
|
||||
[features]
|
||||
coconut = ["coconut-interface", "credentials", "gateway-requests/coconut", "gateway-client/coconut", "credentials/coconut", "client-core/coconut"]
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::template::config_template;
|
||||
use client_core::config::Config as BaseConfig;
|
||||
pub use client_core::config::MISSING_VALUE;
|
||||
use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig};
|
||||
use config::defaults::DEFAULT_SOCKS5_LISTENING_PORT;
|
||||
use config::NymConfig;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
@@ -52,12 +52,6 @@ impl NymConfig for Config {
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientCoreConfigTrait for Config {
|
||||
fn get_gateway_endpoint(&self) -> &client_core::config::GatewayEndpointConfig {
|
||||
self.base.get_gateway_endpoint()
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new<S: Into<String>>(id: S, provider_mix_address: S) -> Self {
|
||||
Config {
|
||||
@@ -66,13 +60,11 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_port(mut self, port: u16) -> Self {
|
||||
self.socks5.listening_port = port;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_provider_mix_address(mut self, address: String) -> Self {
|
||||
self.socks5.provider_mix_address = address;
|
||||
self
|
||||
|
||||
@@ -131,8 +131,11 @@ impl NymClient {
|
||||
}
|
||||
|
||||
/// blocking version of `start` method. Will run forever (or until SIGINT is sent)
|
||||
pub async fn run_forever(self) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
let mut shutdown = self.start().await?;
|
||||
pub async fn run_forever(self) -> Result<(), Box<dyn Error + Send>> {
|
||||
let mut shutdown = self
|
||||
.start()
|
||||
.await
|
||||
.map_err(|err| Box::new(err) as Box<dyn Error + Send>)?;
|
||||
|
||||
let res = wait_for_signal_and_error(&mut shutdown).await;
|
||||
|
||||
@@ -150,9 +153,12 @@ impl NymClient {
|
||||
pub async fn run_and_listen(
|
||||
self,
|
||||
mut receiver: Socks5ControlMessageReceiver,
|
||||
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
) -> Result<(), Box<dyn Error + Send>> {
|
||||
// Start the main task
|
||||
let mut shutdown = self.start().await?;
|
||||
let mut shutdown = self
|
||||
.start()
|
||||
.await
|
||||
.map_err(|err| Box::new(err) as Box<dyn Error + Send>)?;
|
||||
|
||||
let res = tokio::select! {
|
||||
biased;
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use clap::Args;
|
||||
use client_core::{config::GatewayEndpointConfig, error::ClientCoreError};
|
||||
use config::NymConfig;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use serde::Serialize;
|
||||
use tap::TapFallible;
|
||||
|
||||
use crate::{
|
||||
client::config::Config,
|
||||
commands::{override_config, OverrideConfig},
|
||||
error::Socks5ClientError,
|
||||
};
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
@@ -60,10 +55,6 @@ pub(crate) struct Init {
|
||||
#[cfg(feature = "coconut")]
|
||||
#[clap(long)]
|
||||
enabled_credentials_mode: bool,
|
||||
|
||||
/// Save a summary of the initialization to a json file
|
||||
#[clap(long)]
|
||||
output_json: bool,
|
||||
}
|
||||
|
||||
impl From<Init> for OverrideConfig {
|
||||
@@ -80,30 +71,7 @@ impl From<Init> for OverrideConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct InitResults {
|
||||
#[serde(flatten)]
|
||||
client_core: client_core::init::InitResults,
|
||||
socks5_listening_port: String,
|
||||
}
|
||||
|
||||
impl InitResults {
|
||||
fn new(config: &Config, address: &Recipient) -> Self {
|
||||
Self {
|
||||
client_core: client_core::init::InitResults::new(config.get_base(), address),
|
||||
socks5_listening_port: config.get_listening_port().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for InitResults {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "{}", self.client_core)?;
|
||||
write!(f, "SOCKS5 listening port: {}", self.socks5_listening_port)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
|
||||
pub(crate) async fn execute(args: &Init) {
|
||||
println!("Initialising client...");
|
||||
|
||||
let id = &args.id;
|
||||
@@ -128,47 +96,25 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
|
||||
let register_gateway = !already_init || user_wants_force_register;
|
||||
|
||||
// Attempt to use a user-provided gateway, if possible
|
||||
let user_chosen_gateway_id = args.gateway.clone();
|
||||
let user_chosen_gateway_id = args.gateway.as_deref();
|
||||
|
||||
// Load and potentially override config
|
||||
let mut config = override_config(
|
||||
Config::new(id, provider_address),
|
||||
OverrideConfig::from(args.clone()),
|
||||
);
|
||||
|
||||
// Setup gateway by either registering a new one, or creating a new config from the selected
|
||||
// one but with keys kept, or reusing the gateway configuration.
|
||||
let gateway = client_core::init::setup_gateway::<Config, _>(
|
||||
register_gateway,
|
||||
user_chosen_gateway_id,
|
||||
config.get_base(),
|
||||
)
|
||||
.await
|
||||
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
||||
let mut config = Config::new(id, provider_address);
|
||||
let override_config_fields = OverrideConfig::from(args.clone());
|
||||
config = override_config(config, override_config_fields);
|
||||
|
||||
let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config)
|
||||
.await
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Failed to setup gateway\nError: {err}");
|
||||
std::process::exit(1)
|
||||
});
|
||||
config.get_base_mut().with_gateway_endpoint(gateway);
|
||||
|
||||
config.save_to_file(None).tap_err(|_| {
|
||||
log::error!("Failed to save the config file");
|
||||
})?;
|
||||
|
||||
print_saved_config(&config);
|
||||
|
||||
let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?;
|
||||
let init_results = InitResults::new(&config, &address);
|
||||
println!("{}", init_results);
|
||||
|
||||
// Output summary to a json file, if specified
|
||||
if args.output_json {
|
||||
client_core::init::output_to_json(&init_results, "socks5_client_init_results.json");
|
||||
}
|
||||
|
||||
println!("\nThe address of this client is: {}\n", address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_saved_config(config: &Config) {
|
||||
let config_save_location = config.get_config_file_save_location();
|
||||
config
|
||||
.save_to_file(None)
|
||||
.expect("Failed to save the config file");
|
||||
|
||||
println!("Saved configuration file to {:?}", config_save_location);
|
||||
println!("Using gateway: {}", config.get_base().get_gateway_id());
|
||||
log::debug!("Gateway id: {}", config.get_base().get_gateway_id());
|
||||
@@ -177,5 +123,62 @@ fn print_saved_config(config: &Config) {
|
||||
"Gateway listener: {}",
|
||||
config.get_base().get_gateway_listener()
|
||||
);
|
||||
println!("Client configuration completed.\n");
|
||||
println!("Client configuration completed.");
|
||||
|
||||
client_core::init::show_address(config.get_base()).unwrap_or_else(|err| {
|
||||
eprintln!("Failed to show address\nError: {err}");
|
||||
std::process::exit(1)
|
||||
});
|
||||
}
|
||||
|
||||
async fn setup_gateway(
|
||||
id: &str,
|
||||
register: bool,
|
||||
user_chosen_gateway_id: Option<&str>,
|
||||
config: &Config,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||
if register {
|
||||
// Get the gateway details by querying the validator-api. Either pick one at random or use
|
||||
// the chosen one if it's among the available ones.
|
||||
println!("Configuring gateway");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
|
||||
// Registering with gateway by setting up and writing shared keys to disk
|
||||
log::trace!("Registering gateway");
|
||||
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
|
||||
.await?;
|
||||
println!("Saved all generated keys");
|
||||
|
||||
Ok(gateway.into())
|
||||
} else if user_chosen_gateway_id.is_some() {
|
||||
// Just set the config, don't register or create any keys
|
||||
// This assumes that the user knows what they are doing, and that the existing keys are
|
||||
// valid for the gateway being used
|
||||
println!("Using gateway provided by user, keeping existing keys");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
Ok(gateway.into())
|
||||
} else {
|
||||
println!("Not registering gateway, will reuse existing config and keys");
|
||||
let existing_config = Config::load_from_file(Some(id)).map_err(|err| {
|
||||
log::error!(
|
||||
"Unable to configure gateway: {err}. \n
|
||||
Seems like the client was already initialized but it was not possible to read \
|
||||
the existing configuration file. \n
|
||||
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
|
||||
removing the existing configuration and starting over."
|
||||
);
|
||||
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
|
||||
})?;
|
||||
Ok(existing_config.get_base().get_gateway_endpoint().clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@ pub(crate) struct OverrideConfig {
|
||||
enabled_credentials_mode: bool,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send>> {
|
||||
let bin_name = "nym-socks5-client";
|
||||
|
||||
match &args.command {
|
||||
Commands::Init(m) => init::execute(m).await?,
|
||||
Commands::Init(m) => init::execute(m).await,
|
||||
Commands::Run(m) => run::execute(m).await?,
|
||||
Commands::Upgrade(m) => upgrade::execute(m),
|
||||
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
|
||||
|
||||
@@ -95,7 +95,7 @@ fn version_check(cfg: &Config) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
pub(crate) async fn execute(args: &Run) -> Result<(), Box<dyn std::error::Error + Send>> {
|
||||
let id = &args.id;
|
||||
|
||||
let mut config = match Config::load_from_file(Some(id)) {
|
||||
|
||||
@@ -13,7 +13,7 @@ pub mod error;
|
||||
pub mod socks;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
async fn main() -> Result<(), Box<dyn Error + Send>> {
|
||||
setup_logging();
|
||||
println!("{}", banner());
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use snafu::Snafu;
|
||||
|
||||
/// SOCKS4 Response codes
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum ResponseCodeV4 {
|
||||
@@ -8,26 +10,24 @@ pub(crate) enum ResponseCodeV4 {
|
||||
}
|
||||
|
||||
/// Possible SOCKS5 Response Codes
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, Snafu)]
|
||||
pub(crate) enum ResponseCodeV5 {
|
||||
#[error("SOCKS5 Server Success")]
|
||||
Success = 0x00,
|
||||
#[error("SOCKS5 Server Failure")]
|
||||
#[snafu(display("SOCKS5 Server Failure"))]
|
||||
Failure = 0x01,
|
||||
#[error("SOCKS5 Rule failure")]
|
||||
#[snafu(display("SOCKS5 Rule failure"))]
|
||||
RuleFailure = 0x02,
|
||||
#[error("network unreachable")]
|
||||
#[snafu(display("network unreachable"))]
|
||||
NetworkUnreachable = 0x03,
|
||||
#[error("host unreachable")]
|
||||
#[snafu(display("host unreachable"))]
|
||||
HostUnreachable = 0x04,
|
||||
#[error("connection refused")]
|
||||
#[snafu(display("connection refused"))]
|
||||
ConnectionRefused = 0x05,
|
||||
#[error("TTL expired")]
|
||||
#[snafu(display("TTL expired"))]
|
||||
TtlExpired = 0x06,
|
||||
#[error("Command not supported")]
|
||||
#[snafu(display("Command not supported"))]
|
||||
CommandNotSupported = 0x07,
|
||||
#[error("Addr Type not supported")]
|
||||
#[snafu(display("Addr Type not supported"))]
|
||||
AddrTypeNotSupported = 0x08,
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ where
|
||||
#[cfg(feature = "coconut")]
|
||||
pub async fn prepare_coconut_credential(
|
||||
&self,
|
||||
) -> Result<(coconut_interface::Credential, i64), GatewayClientError> {
|
||||
) -> Result<coconut_interface::Credential, GatewayClientError> {
|
||||
let verification_key = obtain_aggregate_verification_key(&self.coconut_api_clients).await?;
|
||||
let bandwidth_credential = self.storage.get_next_coconut_credential().await?;
|
||||
let voucher_value = u64::from_str(&bandwidth_credential.voucher_value)
|
||||
@@ -75,21 +75,13 @@ where
|
||||
coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?;
|
||||
|
||||
// the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff)
|
||||
Ok((
|
||||
prepare_for_spending(
|
||||
voucher_value,
|
||||
voucher_info,
|
||||
serial_number,
|
||||
binding_number,
|
||||
&signature,
|
||||
&verification_key,
|
||||
)?,
|
||||
bandwidth_credential.id,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
pub async fn consume_credential(&self, id: i64) -> Result<(), GatewayClientError> {
|
||||
Ok(self.storage.consume_coconut_credential(id).await?)
|
||||
Ok(prepare_for_spending(
|
||||
voucher_value,
|
||||
voucher_info,
|
||||
serial_number,
|
||||
binding_number,
|
||||
&signature,
|
||||
&verification_key,
|
||||
)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +587,7 @@ impl GatewayClient {
|
||||
let _gateway_owner = self.gateway_owner.clone();
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
let (credential, credential_id) = self
|
||||
let credential = self
|
||||
.bandwidth_controller
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
@@ -597,15 +597,7 @@ impl GatewayClient {
|
||||
return self.try_claim_testnet_bandwidth().await;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
{
|
||||
self.claim_coconut_bandwidth(credential).await?;
|
||||
self.bandwidth_controller
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.consume_credential(credential_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
return self.claim_coconut_bandwidth(credential).await;
|
||||
}
|
||||
|
||||
fn estimate_required_bandwidth(&self, packets: &[MixPacket]) -> i64 {
|
||||
|
||||
@@ -39,7 +39,7 @@ pub trait Storage: Send + Sync {
|
||||
|
||||
async fn get_next_coconut_credential(&self) -> Result<CoconutCredential, StorageError>;
|
||||
|
||||
async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError>;
|
||||
async fn remove_coconut_credential(&self, id: i64) -> Result<(), StorageError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -59,7 +59,7 @@ impl Storage for PersistentStorage {
|
||||
Err(StorageError::WasmNotSupported)
|
||||
}
|
||||
|
||||
async fn consume_coconut_credential(&self, _id: i64) -> Result<(), StorageError> {
|
||||
async fn remove_coconut_credential(&self, _id: i64) -> Result<(), StorageError> {
|
||||
Err(StorageError::WasmNotSupported)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
DROP TABLE coconut_credentials;
|
||||
CREATE TABLE coconut_credentials
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
voucher_value TEXT NOT NULL,
|
||||
voucher_info TEXT NOT NULL,
|
||||
serial_number TEXT NOT NULL,
|
||||
binding_number TEXT NOT NULL,
|
||||
signature TEXT NOT NULL UNIQUE,
|
||||
consumed BOOLEAN NOT NULL
|
||||
);
|
||||
@@ -36,8 +36,8 @@ impl CoconutCredentialManager {
|
||||
signature: String,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
"INSERT INTO coconut_credentials(voucher_value, voucher_info, serial_number, binding_number, signature, consumed) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
voucher_value, voucher_info, serial_number, binding_number, signature, false
|
||||
"INSERT INTO coconut_credentials(voucher_value, voucher_info, serial_number, binding_number, signature) VALUES (?, ?, ?, ?, ?)",
|
||||
voucher_value, voucher_info, serial_number, binding_number, signature
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
@@ -48,26 +48,20 @@ impl CoconutCredentialManager {
|
||||
pub(crate) async fn get_next_coconut_credential(
|
||||
&self,
|
||||
) -> Result<CoconutCredential, sqlx::Error> {
|
||||
sqlx::query_as!(
|
||||
CoconutCredential,
|
||||
"SELECT * FROM coconut_credentials WHERE NOT consumed"
|
||||
)
|
||||
.fetch_one(&self.connection_pool)
|
||||
.await
|
||||
sqlx::query_as!(CoconutCredential, "SELECT * FROM coconut_credentials")
|
||||
.fetch_one(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Consumes in the database the specified credential.
|
||||
/// Removes from the database the specified credential.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `id`: Database id.
|
||||
pub(crate) async fn consume_coconut_credential(&self, id: i64) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
"UPDATE coconut_credentials SET consumed = TRUE WHERE id = ?",
|
||||
id
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
pub(crate) async fn remove_coconut_credential(&self, id: i64) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!("DELETE FROM coconut_credentials WHERE id = ?", id)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +93,9 @@ impl Storage for PersistentStorage {
|
||||
Ok(credential)
|
||||
}
|
||||
|
||||
async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> {
|
||||
async fn remove_coconut_credential(&self, id: i64) -> Result<(), StorageError> {
|
||||
self.coconut_credential_manager
|
||||
.consume_coconut_credential(id)
|
||||
.remove_coconut_credential(id)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -9,5 +9,4 @@ pub struct CoconutCredential {
|
||||
pub serial_number: String,
|
||||
pub binding_number: String,
|
||||
pub signature: String,
|
||||
pub consumed: bool,
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ pub trait Storage: Send + Sync {
|
||||
/// Tries to retrieve one of the stored, unused credentials.
|
||||
async fn get_next_coconut_credential(&self) -> Result<CoconutCredential, StorageError>;
|
||||
|
||||
/// Marks as consumed in the database the specified credential.
|
||||
/// Removes from the database the specified credential.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `id`: Id of the credential to be consumed.
|
||||
async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError>;
|
||||
/// * `signature`: Coconut credential in the form of a signature.
|
||||
async fn remove_coconut_credential(&self, id: i64) -> Result<(), StorageError>;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ impl PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct PublicKeyWithProof {
|
||||
pub(crate) key: PublicKey,
|
||||
|
||||
@@ -13,7 +13,7 @@ use zeroize::Zeroize;
|
||||
const DISCRETE_LOG_DOMAIN: &[u8] =
|
||||
b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG";
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct ProofOfDiscreteLog {
|
||||
pub(crate) rand_commitment: G1Projective,
|
||||
|
||||
@@ -9,79 +9,19 @@ use crate::interpolation::polynomial::{Polynomial, PublicCoefficients};
|
||||
use crate::interpolation::{
|
||||
perform_lagrangian_interpolation_at_origin, perform_lagrangian_interpolation_at_x,
|
||||
};
|
||||
use crate::utils::deserialize_g2;
|
||||
use crate::{NodeIndex, Share, Threshold};
|
||||
use bls12_381::{G2Projective, Scalar};
|
||||
use group::GroupEncoding;
|
||||
use rand_core::RngCore;
|
||||
use std::collections::BTreeMap;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct RecoveredVerificationKeys {
|
||||
pub recovered_master: G2Projective,
|
||||
pub recovered_partials: Vec<G2Projective>,
|
||||
}
|
||||
|
||||
impl RecoveredVerificationKeys {
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let partials = self.recovered_partials.len();
|
||||
let mut bytes = Vec::with_capacity(96 + 4 + 96 * partials);
|
||||
bytes.extend_from_slice(self.recovered_master.to_bytes().as_ref());
|
||||
bytes.extend_from_slice(&((partials as u32).to_be_bytes()));
|
||||
for partial in &self.recovered_partials {
|
||||
bytes.extend_from_slice(partial.to_bytes().as_ref());
|
||||
}
|
||||
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn try_from_bytes(b: &[u8]) -> Result<Self, DkgError> {
|
||||
if b.len() < 96 + 4 {
|
||||
return Err(DkgError::new_deserialization_failure(
|
||||
"RecoveredVerificationKeys",
|
||||
"insufficient number of bytes provided",
|
||||
));
|
||||
}
|
||||
|
||||
let recovered_master = deserialize_g2(&b[..96]).ok_or_else(|| {
|
||||
DkgError::new_deserialization_failure(
|
||||
"RecoveredVerificationKeys.recovered_master",
|
||||
"invalid curve point",
|
||||
)
|
||||
})?;
|
||||
|
||||
let partials = u32::from_be_bytes([b[96], b[97], b[98], b[99]]) as usize;
|
||||
let mut recovered_partials = Vec::with_capacity(partials);
|
||||
|
||||
if b.len() != 96 + 4 + 96 * partials {
|
||||
return Err(DkgError::new_deserialization_failure(
|
||||
"RecoveredVerificationKeys",
|
||||
"insufficient number of bytes provided",
|
||||
));
|
||||
}
|
||||
|
||||
let mut i = 96 + 4;
|
||||
for _ in 0..partials {
|
||||
let partial = deserialize_g2(&b[i..i + 96]).ok_or_else(|| {
|
||||
DkgError::new_deserialization_failure(
|
||||
"RecoveredVerificationKeys.recovered_partials",
|
||||
"invalid curve point",
|
||||
)
|
||||
})?;
|
||||
|
||||
recovered_partials.push(partial);
|
||||
i += 96;
|
||||
}
|
||||
|
||||
Ok(RecoveredVerificationKeys {
|
||||
recovered_master,
|
||||
recovered_partials,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct Dealing {
|
||||
@@ -415,17 +355,6 @@ mod tests {
|
||||
use crate::combine_shares;
|
||||
use rand_core::SeedableRng;
|
||||
|
||||
#[test]
|
||||
fn recovered_verification_keys_serde() {
|
||||
let keys = RecoveredVerificationKeys {
|
||||
recovered_master: Default::default(),
|
||||
recovered_partials: vec![Default::default(), Default::default()],
|
||||
};
|
||||
let bytes = keys.to_bytes();
|
||||
let recovered_keys = RecoveredVerificationKeys::try_from_bytes(&bytes).unwrap();
|
||||
assert_eq!(keys, recovered_keys);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // expensive test
|
||||
fn recovering_partial_verification_keys() {
|
||||
|
||||
@@ -9,7 +9,7 @@ pub(crate) const BECH32_PREFIX: &str = "n";
|
||||
pub const MIX_DENOM: DenomDetails = DenomDetails::new("unym", "nym", 6);
|
||||
pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6);
|
||||
|
||||
pub const MIXNET_CONTRACT_ADDRESS: &str =
|
||||
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
|
||||
"n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr";
|
||||
pub(crate) const VESTING_CONTRACT_ADDRESS: &str =
|
||||
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
|
||||
@@ -25,7 +25,7 @@ pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
|
||||
hex_literal::hex!("0000000000000000000000000000000000000000");
|
||||
pub(crate) const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
|
||||
|
||||
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
|
||||
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
|
||||
pub const NYMD_VALIDATOR: &str = "https://rpc.nymtech.net";
|
||||
pub const API_VALIDATOR: &str = "https://validator.nymtech.net/api/";
|
||||
pub(crate) fn validators() -> Vec<ValidatorDetails> {
|
||||
|
||||
@@ -14,7 +14,7 @@ use tokio::{
|
||||
|
||||
const DEFAULT_SHUTDOWN_TIMER_SECS: u64 = 5;
|
||||
|
||||
pub(crate) type SentError = Box<dyn Error + Send + Sync>;
|
||||
pub(crate) type SentError = Box<dyn Error + Send>;
|
||||
type ErrorSender = mpsc::UnboundedSender<SentError>;
|
||||
type ErrorReceiver = mpsc::UnboundedReceiver<SentError>;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ pub fn spawn_with_report_error<F, T, E>(future: F, mut shutdown: ShutdownListene
|
||||
where
|
||||
F: Future<Output = Result<T, E>> + Send + 'static,
|
||||
T: 'static,
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
E: std::error::Error + Send + 'static,
|
||||
{
|
||||
let future_that_sends = async move {
|
||||
if let Err(err) = future.await {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::config::template::config_template;
|
||||
use config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||
use config::NymConfig;
|
||||
use log::error;
|
||||
use network_defaults::mainnet::{API_VALIDATOR, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
@@ -417,9 +416,9 @@ impl Default for Gateway {
|
||||
private_sphinx_key_file: Default::default(),
|
||||
public_sphinx_key_file: Default::default(),
|
||||
enabled_statistics: false,
|
||||
statistics_service_url: Url::from_str(STATISTICS_SERVICE_DOMAIN_ADDRESS).expect("Invalid default statistics service URL"),
|
||||
validator_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")],
|
||||
validator_nymd_urls: vec![Url::from_str(NYMD_VALIDATOR).expect("Invalid default nymd URL")],
|
||||
statistics_service_url: Url::from_str("http://127.0.0.1").unwrap(),
|
||||
validator_api_urls: vec![],
|
||||
validator_nymd_urls: vec![],
|
||||
cosmos_mnemonic: bip39::Mnemonic::from_str("exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day").unwrap(),
|
||||
nym_root_directory: Config::default_root_directory(),
|
||||
persistent_storage: Default::default(),
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::template::config_template;
|
||||
use config::defaults::mainnet::API_VALIDATOR;
|
||||
use config::defaults::{
|
||||
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
||||
};
|
||||
@@ -412,7 +411,7 @@ impl Default for MixNode {
|
||||
public_identity_key_file: Default::default(),
|
||||
private_sphinx_key_file: Default::default(),
|
||||
public_sphinx_key_file: Default::default(),
|
||||
validator_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")],
|
||||
validator_api_urls: vec![],
|
||||
nym_root_directory: Config::default_root_directory(),
|
||||
wallet_address: "nymXXXXXXXX".to_string(),
|
||||
}
|
||||
@@ -492,9 +491,6 @@ struct Debug {
|
||||
maximum_connection_buffer_size: usize,
|
||||
|
||||
/// Specifies whether the mixnode should be using the legacy framing for the sphinx packets.
|
||||
// it's set to true by default. The reason for that decision is to preserve compatibility with the
|
||||
// existing nodes whilst everyone else is upgrading and getting the code for handling the new field.
|
||||
// It shall be disabled in the subsequent releases.
|
||||
use_legacy_framed_packet_version: bool,
|
||||
}
|
||||
|
||||
@@ -507,8 +503,7 @@ impl Default for Debug {
|
||||
packet_forwarding_maximum_backoff: DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF,
|
||||
initial_connection_timeout: DEFAULT_INITIAL_CONNECTION_TIMEOUT,
|
||||
maximum_connection_buffer_size: DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE,
|
||||
// TODO: remember to change it in one of future releases!!
|
||||
use_legacy_framed_packet_version: true,
|
||||
use_legacy_framed_packet_version: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
## UNRELEASED
|
||||
|
||||
## [nym-connect-v1.1.3](https://github.com/nymtech/nym/tree/nym-connect-v1.1.3) (2022-12-13)
|
||||
|
||||
- socks5-client: added support for socks4a.
|
||||
|
||||
## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-11-29)
|
||||
|
||||
- socks5-client: fix error with client failing and disconnecting unnecessarily.
|
||||
|
||||
Generated
+31
-5
@@ -647,7 +647,6 @@ dependencies = [
|
||||
"pemstore",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sled",
|
||||
"tap",
|
||||
"task",
|
||||
@@ -1416,6 +1415,12 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
@@ -3371,7 +3376,7 @@ dependencies = [
|
||||
"proxy-helpers",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"snafu",
|
||||
"socks5-requests",
|
||||
"tap",
|
||||
"task",
|
||||
@@ -4813,9 +4818,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.89"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
dependencies = [
|
||||
"itoa 1.0.3",
|
||||
"ryu",
|
||||
@@ -5033,6 +5038,27 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"snafu-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu-derive"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
@@ -6274,7 +6300,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "vesting-contract"
|
||||
version = "1.1.2"
|
||||
version = "1.1.0"
|
||||
dependencies = [
|
||||
"contracts-common",
|
||||
"cosmwasm-std",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nym/nym-connect",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.2",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-connect"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
description = "nym-connect"
|
||||
authors = ["Nym Technologies SA"]
|
||||
license = ""
|
||||
@@ -32,7 +32,7 @@ reqwest = { version = "0.11", features = ["json"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tap = "1.0.1"
|
||||
tauri = { version = "^1.1.1", features = ["clipboard-write-text", "macos-private-api", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] }
|
||||
tauri = { version = "^1.1.1", features = ["clipboard-write-text", "macos-private-api", "shell-open", "system-tray", "updater", "window-close", "window-start-dragging"] }
|
||||
tendermint-rpc = "0.23.0"
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1.21.2", features = ["sync", "time"] }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use client_core::config::GatewayEndpointConfig;
|
||||
use std::sync::Arc;
|
||||
use tap::TapFallible;
|
||||
use tokio::sync::RwLock;
|
||||
@@ -115,9 +116,6 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
|
||||
// Future proofing. This flag exists for the other clients
|
||||
let user_wants_force_register = false;
|
||||
|
||||
// If the client was already initialized, don't generate new keys and don't re-register with
|
||||
// the gateway (because this would create a new shared key).
|
||||
// Unless the user really wants to.
|
||||
let register_gateway = !already_init || user_wants_force_register;
|
||||
|
||||
log::trace!("Creating config for id: {}", id);
|
||||
@@ -129,38 +127,28 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
|
||||
.set_custom_validator_apis(config_common::parse_validators(&raw_validators));
|
||||
}
|
||||
|
||||
// Setup gateway by either registering a new one, or reusing exiting keys
|
||||
let gateway = client_core::init::setup_gateway::<Socks5Config, _>(
|
||||
let gateway = setup_gateway(
|
||||
&id,
|
||||
register_gateway,
|
||||
Some(chosen_gateway_id),
|
||||
config.get_base(),
|
||||
Some(&chosen_gateway_id),
|
||||
config.get_socks5(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
config.get_base_mut().with_gateway_endpoint(gateway);
|
||||
|
||||
let config_save_location = config.get_socks5().get_config_file_save_location();
|
||||
config.get_socks5().save_to_file(None).tap_err(|_| {
|
||||
log::error!("Failed to save the config file");
|
||||
})?;
|
||||
|
||||
print_saved_config(&config);
|
||||
|
||||
let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?;
|
||||
log::info!("The address of this client is: {}", address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_saved_config(config: &Config) {
|
||||
log::info!(
|
||||
"Saved configuration file to {:?}",
|
||||
config.get_socks5().get_config_file_save_location()
|
||||
);
|
||||
log::info!("Saved configuration file to {:?}", config_save_location);
|
||||
log::info!("Gateway id: {}", config.get_base().get_gateway_id());
|
||||
log::info!("Gateway owner: {}", config.get_base().get_gateway_owner());
|
||||
log::info!(
|
||||
"Gateway listener: {}",
|
||||
config.get_base().get_gateway_listener()
|
||||
);
|
||||
|
||||
log::info!(
|
||||
"Service provider address: {}",
|
||||
config.get_socks5().get_provider_mix_address()
|
||||
@@ -170,4 +158,60 @@ fn print_saved_config(config: &Config) {
|
||||
config.get_socks5().get_listening_port()
|
||||
);
|
||||
log::info!("Client configuration completed.");
|
||||
|
||||
client_core::init::show_address(config.get_base())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: deduplicate with same functions in other client
|
||||
async fn setup_gateway(
|
||||
id: &str,
|
||||
register: bool,
|
||||
user_chosen_gateway_id: Option<&str>,
|
||||
config: &Socks5Config,
|
||||
) -> Result<GatewayEndpointConfig> {
|
||||
if register {
|
||||
// Get the gateway details by querying the validator-api. Either pick one at random or use
|
||||
// the chosen one if it's among the available ones.
|
||||
println!("Configuring gateway");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
|
||||
// Registering with gateway by setting up and writing shared keys to disk
|
||||
log::trace!("Registering gateway");
|
||||
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
|
||||
.await?;
|
||||
println!("Saved all generated keys");
|
||||
|
||||
Ok(gateway.into())
|
||||
} else if user_chosen_gateway_id.is_some() {
|
||||
// Just set the config, don't register or create any keys
|
||||
// This assumes that the user knows what they are doing, and that the existing keys are
|
||||
// valid for the gateway being used
|
||||
println!("Using gateway provided by user, keeping existing keys");
|
||||
let gateway = client_core::init::query_gateway_details(
|
||||
config.get_base().get_validator_api_endpoints(),
|
||||
user_chosen_gateway_id,
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Querying gateway gives: {}", gateway);
|
||||
Ok(gateway.into())
|
||||
} else {
|
||||
println!("Not registering gateway, will reuse existing config and keys");
|
||||
let existing_config = Socks5Config::load_from_file(Some(id)).map_err(|err| {
|
||||
log::error!(
|
||||
"Unable to configure gateway: {err}. \n
|
||||
Seems like the client was already initialized but it was not possible to read \
|
||||
the existing configuration file. \n
|
||||
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
|
||||
removing the existing configuration and starting over."
|
||||
);
|
||||
BackendError::CouldNotLoadExistingGatewayConfiguration(err)
|
||||
})?;
|
||||
Ok(existing_config.get_base().get_gateway_endpoint().clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use client_core::config::{ClientCoreConfigTrait, GatewayEndpointConfig};
|
||||
use client_core::config::GatewayEndpointConfig;
|
||||
use futures::channel::mpsc;
|
||||
use std::sync::Arc;
|
||||
use tap::TapFallible;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-connect",
|
||||
"version": "1.1.3"
|
||||
"version": "1.1.2"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
@@ -57,8 +57,7 @@
|
||||
},
|
||||
"window": {
|
||||
"startDragging": true,
|
||||
"close": true,
|
||||
"minimize": true
|
||||
"close": true
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { ArrowBack, Close, HelpOutline, Minimize } from '@mui/icons-material';
|
||||
import { ArrowBack, Close, HelpOutline } from '@mui/icons-material';
|
||||
import { Box, IconButton } from '@mui/material';
|
||||
import { NymWordmark } from '@nymproject/react/logo/NymWordmark';
|
||||
import { appWindow } from '@tauri-apps/api/window';
|
||||
@@ -19,7 +19,7 @@ const customTitleBarStyles = {
|
||||
};
|
||||
|
||||
const CustomButton = ({ Icon, onClick }: { Icon: React.JSXElementConstructor<any>; onClick: () => void }) => (
|
||||
<IconButton size="small" onClick={onClick} sx={{ padding: 0 }}>
|
||||
<IconButton size="small" style={{ padding: 0 }} onClick={onClick}>
|
||||
<Icon style={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
);
|
||||
@@ -28,22 +28,14 @@ export const CustomTitleBar = () => {
|
||||
const { showHelp, handleShowHelp } = useClientContext();
|
||||
return (
|
||||
<Box data-tauri-drag-region style={customTitleBarStyles.titlebar}>
|
||||
{/* set width to keep logo centered */}
|
||||
<Box sx={{ width: '40px' }}>
|
||||
<CustomButton
|
||||
Icon={!showHelp ? HelpOutline : ArrowBack}
|
||||
onClick={() => {
|
||||
handleShowHelp();
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<CustomButton
|
||||
Icon={!showHelp ? HelpOutline : ArrowBack}
|
||||
onClick={() => {
|
||||
handleShowHelp();
|
||||
}}
|
||||
/>
|
||||
<NymWordmark width={36} />
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<CustomButton Icon={Minimize} onClick={() => appWindow.minimize()} />
|
||||
<CustomButton Icon={Close} onClick={() => appWindow.close()} />
|
||||
</Box>
|
||||
<CustomButton Icon={Close} onClick={() => appWindow.close()} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [nym-wallet-v1.1.3](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.3) (2022-12-13)
|
||||
|
||||
- wallet: improved unbond screen.
|
||||
|
||||
## [nym-wallet-v1.1.2](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.2) (2022-11-09)
|
||||
|
||||
- wallet: Bity buy functionality
|
||||
|
||||
Generated
+1
-1
@@ -5497,7 +5497,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "vesting-contract"
|
||||
version = "1.1.2"
|
||||
version = "1.1.0"
|
||||
dependencies = [
|
||||
"contracts-common",
|
||||
"cosmwasm-std",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/nym-wallet-app",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.2",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym_wallet"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
description = "Nym Native Wallet"
|
||||
authors = ["Nym Technologies SA"]
|
||||
license = ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-wallet",
|
||||
"version": "1.1.3"
|
||||
"version": "1.1.2"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
|
||||
@@ -16,6 +16,7 @@ const TutorialStep = ({
|
||||
icon,
|
||||
borderRight,
|
||||
borderBottom,
|
||||
fixTitleHeight,
|
||||
}: {
|
||||
step: number;
|
||||
title: string;
|
||||
@@ -23,6 +24,7 @@ const TutorialStep = ({
|
||||
icon: React.ReactNode;
|
||||
borderRight?: boolean;
|
||||
borderBottom?: boolean;
|
||||
fixTitleHeight?: boolean;
|
||||
}) => (
|
||||
<Grid
|
||||
item
|
||||
@@ -41,7 +43,13 @@ const TutorialStep = ({
|
||||
{`STEP ${step}`}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography fontWeight={600} variant="h6">
|
||||
<Typography
|
||||
fontWeight={600}
|
||||
variant="h6"
|
||||
sx={{
|
||||
minHeight: fixTitleHeight ? '40px' : undefined,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{text}
|
||||
@@ -53,6 +61,7 @@ export const Tutorial = () => {
|
||||
const [showSignModal, setShowSignModal] = useState(false);
|
||||
const theme = useTheme();
|
||||
const showBorder = useMediaQuery(theme.breakpoints.up('md'));
|
||||
const fixTitleHeight = useMediaQuery(theme.breakpoints.down('lg'));
|
||||
|
||||
return (
|
||||
<NymCard borderless title="Buy NYM with BTC without KYC" sx={{ mt: 4 }}>
|
||||
@@ -87,10 +96,11 @@ export const Tutorial = () => {
|
||||
}
|
||||
borderRight={showBorder}
|
||||
borderBottom={!showBorder}
|
||||
fixTitleHeight={fixTitleHeight}
|
||||
/>
|
||||
<TutorialStep
|
||||
step={2}
|
||||
title="Sign message"
|
||||
title="Sign a message with your Nym wallet"
|
||||
icon={<BorderColorIcon fontSize="small" />}
|
||||
text={
|
||||
<Typography sx={{ color: (t) => t.palette.nym.text.muted }}>
|
||||
@@ -103,17 +113,19 @@ export const Tutorial = () => {
|
||||
}
|
||||
borderRight={showBorder}
|
||||
borderBottom={!showBorder}
|
||||
fixTitleHeight={fixTitleHeight}
|
||||
/>
|
||||
<TutorialStep
|
||||
step={3}
|
||||
title="Send tx and receive NYM"
|
||||
title="Make BTC tx and receive NYM"
|
||||
icon={<PaidIcon fontSize="small" />}
|
||||
text={
|
||||
<Typography sx={{ color: (t) => t.palette.nym.text.muted }}>
|
||||
{`Send the defined BTC amount to Bity's address that's given to you. As soon as your BTC transaction has 4
|
||||
confirmations, Bity will send the purchased NYM tokens to your wallet.`}
|
||||
Send BTC to the given address. When the transaction is confirmed your purchased NYM tokens will be
|
||||
transferred in your wallet.
|
||||
</Typography>
|
||||
}
|
||||
fixTitleHeight={fixTitleHeight}
|
||||
/>
|
||||
</Grid>
|
||||
<Stack direction="row" gap={2} justifyContent="flex-end" mt={5}>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { Stack, Typography, SxProps } from '@mui/material';
|
||||
import { Link } from '@nymproject/react/link/Link';
|
||||
import { TTransactionDetails } from './types';
|
||||
import { ConfirmationModal } from '../Modals/ConfirmationModal';
|
||||
import { AppContext } from 'src/context';
|
||||
|
||||
export const SendSuccessModal = ({
|
||||
txDetails,
|
||||
@@ -15,35 +14,26 @@ export const SendSuccessModal = ({
|
||||
onClose: () => void;
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
}) => {
|
||||
const { userBalance } = useContext(AppContext);
|
||||
|
||||
const handleClose = async () => {
|
||||
await userBalance.refreshBalances();
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
open
|
||||
onConfirm={handleClose}
|
||||
onClose={handleClose}
|
||||
title=""
|
||||
confirmButton="Done"
|
||||
maxWidth="xs"
|
||||
fullWidth
|
||||
sx={sx}
|
||||
backdropProps={backdropProps}
|
||||
>
|
||||
<Stack alignItems="center" spacing={2}>
|
||||
<Typography>You sent</Typography>
|
||||
{txDetails && (
|
||||
<>
|
||||
<Typography variant="h5">{txDetails.amount}</Typography>
|
||||
<Link href={txDetails.txUrl} target="_blank" sx={{ ml: 1 }} text="View on blockchain" />
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</ConfirmationModal>
|
||||
);
|
||||
};
|
||||
}) => (
|
||||
<ConfirmationModal
|
||||
open
|
||||
onConfirm={onClose}
|
||||
onClose={onClose}
|
||||
title=""
|
||||
confirmButton="Done"
|
||||
maxWidth="xs"
|
||||
fullWidth
|
||||
sx={sx}
|
||||
backdropProps={backdropProps}
|
||||
>
|
||||
<Stack alignItems="center" spacing={2}>
|
||||
<Typography>You sent</Typography>
|
||||
{txDetails && (
|
||||
<>
|
||||
<Typography variant="h5">{txDetails.amount}</Typography>
|
||||
<Link href={txDetails.txUrl} target="_blank" sx={{ ml: 1 }} text="View on blockchain" />
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</ConfirmationModal>
|
||||
);
|
||||
|
||||
+1
-5
@@ -88,11 +88,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
|
||||
|
||||
const getPendingEvents = async () => {
|
||||
const events = await getPendingIntervalEvents();
|
||||
const latestEvent = events
|
||||
.reverse()
|
||||
.find(
|
||||
(evt) => 'ChangeMixCostParams' in evt.event && evt.event.ChangeMixCostParams.mix_id === bondedNode.mixId,
|
||||
) as unknown as
|
||||
const latestEvent = events.reverse().find((evt) => 'ChangeMixCostParams' in evt.event) as unknown as
|
||||
| {
|
||||
id: number;
|
||||
event: {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
@@ -437,7 +437,7 @@ impl ServiceProvider {
|
||||
.await;
|
||||
});
|
||||
|
||||
log::info!("All systems go. Press CTRL-C to stop the server.");
|
||||
println!("\nAll systems go. Press CTRL-C to stop the server.");
|
||||
// for each incoming message from the websocket... (which in 99.99% cases is going to be a mix message)
|
||||
loop {
|
||||
let Some(received) = Self::read_websocket_message(
|
||||
@@ -447,7 +447,7 @@ impl ServiceProvider {
|
||||
.await
|
||||
else {
|
||||
log::error!("The websocket stream has finished!");
|
||||
return Err(NetworkRequesterError::ConnectionClosed);
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let raw_message = received.message;
|
||||
|
||||
@@ -7,7 +7,4 @@ pub enum NetworkRequesterError {
|
||||
|
||||
#[error("Websocket error")]
|
||||
WebsocketConnectionError(#[from] WebsocketConnectionError),
|
||||
|
||||
#[error("Websocket connection closed")]
|
||||
ConnectionClosed,
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ impl Run {
|
||||
.unwrap_or(&DEFAULT_WEBSOCKET_LISTENING_PORT.to_string())
|
||||
);
|
||||
|
||||
log::info!("Starting socks5 service provider");
|
||||
println!("Starting socks5 service provider:");
|
||||
let mut server = core::ServiceProvider::new(
|
||||
uri,
|
||||
self.open_proxy,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-network-statistics"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-cli"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = ["Nym Technologies SA"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-validator-api"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub(crate) enum ComplaintReason {
|
||||
MalformedBTEPublicKey,
|
||||
InvalidBTEPublicKey,
|
||||
MissingDealing,
|
||||
MalformedDealing,
|
||||
DealingVerificationError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::coconut::dkg::client::DkgClient;
|
||||
use crate::coconut::dkg::state::{ConsistentState, PersistentState, State};
|
||||
use crate::coconut::dkg::state::{ConsistentState, State};
|
||||
use crate::coconut::dkg::verification_key::{
|
||||
verification_key_finalization, verification_key_validation,
|
||||
};
|
||||
@@ -63,20 +63,12 @@ impl<R: RngCore + Clone> DkgController<R> {
|
||||
)) {
|
||||
coconut_keypair.set(coconut_keypair_value).await;
|
||||
}
|
||||
let persistent_state =
|
||||
PersistentState::load_from_file(config.persistent_state_path()).unwrap_or_default();
|
||||
|
||||
Ok(DkgController {
|
||||
dkg_client: DkgClient::new(nymd_client),
|
||||
secret_key_path: config.secret_key_path(),
|
||||
verification_key_path: config.verification_key_path(),
|
||||
state: State::new(
|
||||
config.persistent_state_path(),
|
||||
persistent_state,
|
||||
config.get_announce_address(),
|
||||
dkg_keypair,
|
||||
coconut_keypair,
|
||||
),
|
||||
state: State::new(config.get_announce_address(), dkg_keypair, coconut_keypair),
|
||||
rng,
|
||||
polling_rate: config.get_dkg_contract_polling_rate(),
|
||||
})
|
||||
@@ -122,13 +114,6 @@ impl<R: RngCore + Clone> DkgController<R> {
|
||||
};
|
||||
if let Err(e) = ret {
|
||||
warn!("Could not handle this iteration for the epoch state: {}", e);
|
||||
} else if epoch_state != EpochState::InProgress {
|
||||
let persistent_state = PersistentState::from(&self.state);
|
||||
if let Err(e) =
|
||||
persistent_state.save_to_file(self.state.persistent_state_path())
|
||||
{
|
||||
warn!("Could not backup the state for this iteration: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,6 @@ pub(crate) async fn dealing_exchange(
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::coconut::dkg::complaints::ComplaintReason;
|
||||
use crate::coconut::dkg::state::PersistentState;
|
||||
use crate::coconut::tests::DummyClient;
|
||||
use crate::coconut::KeyPair;
|
||||
use coconut_dkg_common::dealer::DealerDetails;
|
||||
@@ -64,7 +62,6 @@ pub(crate) mod tests {
|
||||
use dkg::bte::Params;
|
||||
use rand::rngs::OsRng;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use url::Url;
|
||||
@@ -112,8 +109,6 @@ pub(crate) mod tests {
|
||||
);
|
||||
let params = setup();
|
||||
let mut state = State::new(
|
||||
PathBuf::default(),
|
||||
PersistentState::default(),
|
||||
Url::parse("localhost:8000").unwrap(),
|
||||
DkgKeyPair::new(¶ms, OsRng),
|
||||
KeyPair::new(),
|
||||
@@ -153,53 +148,4 @@ pub(crate) mod tests {
|
||||
.clone();
|
||||
assert_eq!(dealings, new_dealings);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // expensive test
|
||||
async fn invalid_bte_proof_dealing_posted() {
|
||||
let self_index = 2;
|
||||
let dealer_details_db = Arc::new(RwLock::new(HashMap::new()));
|
||||
let dealings_db = Arc::new(RwLock::new(HashMap::new()));
|
||||
let dkg_client = DkgClient::new(
|
||||
DummyClient::new(AccountId::from_str(TEST_VALIDATORS_ADDRESS[0]).unwrap())
|
||||
.with_dealer_details(&dealer_details_db)
|
||||
.with_dealings(&dealings_db),
|
||||
);
|
||||
let params = setup();
|
||||
let mut state = State::new(
|
||||
PathBuf::default(),
|
||||
PersistentState::default(),
|
||||
Url::parse("localhost:8000").unwrap(),
|
||||
DkgKeyPair::new(¶ms, OsRng),
|
||||
KeyPair::new(),
|
||||
);
|
||||
state.set_node_index(Some(self_index));
|
||||
insert_dealers(¶ms, &dealer_details_db);
|
||||
|
||||
dealer_details_db
|
||||
.write()
|
||||
.unwrap()
|
||||
.entry(TEST_VALIDATORS_ADDRESS[1].to_string())
|
||||
.and_modify(|details| {
|
||||
let mut bytes = bs58::decode(details.bte_public_key_with_proof.clone())
|
||||
.into_vec()
|
||||
.unwrap();
|
||||
let last_byte = bytes.last_mut().unwrap();
|
||||
*last_byte += 1;
|
||||
details.bte_public_key_with_proof = bs58::encode(&bytes).into_string();
|
||||
});
|
||||
|
||||
dealing_exchange(&dkg_client, &mut state, OsRng)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
*state
|
||||
.all_dealers()
|
||||
.get(&Addr::unchecked(TEST_VALIDATORS_ADDRESS[1]))
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap_err(),
|
||||
ComplaintReason::InvalidBTEPublicKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,10 @@ pub(crate) async fn public_key_submission(
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::coconut::dkg::state::PersistentState;
|
||||
use crate::coconut::tests::DummyClient;
|
||||
use crate::coconut::KeyPair;
|
||||
use dkg::bte::keys::KeyPair as DkgKeyPair;
|
||||
use rand::rngs::OsRng;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use url::Url;
|
||||
use validator_client::nymd::AccountId;
|
||||
@@ -53,8 +51,6 @@ pub(crate) mod tests {
|
||||
AccountId::from_str(TEST_VALIDATOR_ADDRESS).unwrap(),
|
||||
));
|
||||
let mut state = State::new(
|
||||
PathBuf::default(),
|
||||
PersistentState::default(),
|
||||
Url::parse("localhost:8000").unwrap(),
|
||||
DkgKeyPair::new(&dkg::bte::setup(), OsRng),
|
||||
KeyPair::new(),
|
||||
|
||||
@@ -9,33 +9,13 @@ use coconut_dkg_common::types::EpochState;
|
||||
use cosmwasm_std::Addr;
|
||||
use dkg::bte::{keys::KeyPair as DkgKeyPair, PublicKey, PublicKeyWithProof};
|
||||
use dkg::{NodeIndex, RecoveredVerificationKeys, Threshold};
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use url::Url;
|
||||
|
||||
fn bte_pk_serialize<S: Serializer>(
|
||||
val: &PublicKeyWithProof,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
val.to_bytes().serialize(serializer)
|
||||
}
|
||||
|
||||
fn bte_pk_deserialize<'de, D>(deserializer: D) -> Result<PublicKeyWithProof, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<u8> = Deserialize::deserialize(deserializer)?;
|
||||
PublicKeyWithProof::try_from_bytes(&vec).map_err(|err| Error::custom(format_args!("{:?}", err)))
|
||||
}
|
||||
|
||||
// note: each dealer is also a receiver which simplifies some logic significantly
|
||||
#[derive(Clone, Deserialize, Debug, Serialize)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DkgParticipant {
|
||||
pub(crate) _address: Addr,
|
||||
#[serde(serialize_with = "bte_pk_serialize")]
|
||||
#[serde(deserialize_with = "bte_pk_deserialize")]
|
||||
pub(crate) bte_public_key_with_proof: PublicKeyWithProof,
|
||||
pub(crate) assigned_index: NodeIndex,
|
||||
}
|
||||
@@ -50,10 +30,6 @@ impl TryFrom<DealerDetails> for DkgParticipant {
|
||||
.map_err(|_| ComplaintReason::MalformedBTEPublicKey)?
|
||||
.map_err(|_| ComplaintReason::MalformedBTEPublicKey)?;
|
||||
|
||||
if !bte_public_key_with_proof.verify() {
|
||||
return Err(ComplaintReason::InvalidBTEPublicKey);
|
||||
}
|
||||
|
||||
Ok(DkgParticipant {
|
||||
_address: dealer.address,
|
||||
bte_public_key_with_proof,
|
||||
@@ -91,6 +67,20 @@ pub(crate) trait ConsistentState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct State {
|
||||
announce_address: Url,
|
||||
dkg_keypair: DkgKeyPair,
|
||||
coconut_keypair: CoconutKeyPair,
|
||||
node_index: Option<NodeIndex>,
|
||||
dealers: BTreeMap<Addr, Result<DkgParticipant, ComplaintReason>>,
|
||||
receiver_index: Option<usize>,
|
||||
threshold: Option<Threshold>,
|
||||
recovered_vks: Vec<RecoveredVerificationKeys>,
|
||||
proposal_id: Option<u64>,
|
||||
voted_vks: bool,
|
||||
executed_proposal: bool,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ConsistentState for State {
|
||||
fn node_index_value(&self) -> Result<NodeIndex, CoconutError> {
|
||||
@@ -137,110 +127,27 @@ impl ConsistentState for State {
|
||||
}
|
||||
}
|
||||
|
||||
fn vks_serialize<S: Serializer>(
|
||||
val: &[RecoveredVerificationKeys],
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let vec: Vec<Vec<u8>> = val.iter().map(|vk| vk.to_bytes()).collect();
|
||||
vec.serialize(serializer)
|
||||
}
|
||||
|
||||
fn vks_deserialize<'de, D>(deserializer: D) -> Result<Vec<RecoveredVerificationKeys>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let vec: Vec<Vec<u8>> = Deserialize::deserialize(deserializer)?;
|
||||
vec.into_iter()
|
||||
.map(|b| {
|
||||
RecoveredVerificationKeys::try_from_bytes(&b)
|
||||
.map_err(|err| D::Error::custom(format_args!("{:?}", err)))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
pub(crate) struct PersistentState {
|
||||
node_index: Option<NodeIndex>,
|
||||
dealers: BTreeMap<Addr, Result<DkgParticipant, ComplaintReason>>,
|
||||
receiver_index: Option<usize>,
|
||||
threshold: Option<Threshold>,
|
||||
#[serde(serialize_with = "vks_serialize")]
|
||||
#[serde(deserialize_with = "vks_deserialize")]
|
||||
recovered_vks: Vec<RecoveredVerificationKeys>,
|
||||
proposal_id: Option<u64>,
|
||||
voted_vks: bool,
|
||||
executed_proposal: bool,
|
||||
}
|
||||
|
||||
impl From<&State> for PersistentState {
|
||||
fn from(s: &State) -> Self {
|
||||
PersistentState {
|
||||
node_index: s.node_index,
|
||||
dealers: s.dealers.clone(),
|
||||
receiver_index: s.receiver_index,
|
||||
threshold: s.threshold,
|
||||
recovered_vks: s.recovered_vks.clone(),
|
||||
proposal_id: s.proposal_id,
|
||||
voted_vks: s.voted_vks,
|
||||
executed_proposal: s.executed_proposal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PersistentState {
|
||||
pub fn save_to_file(&self, path: PathBuf) -> Result<(), CoconutError> {
|
||||
std::fs::write(path, serde_json::to_string(self)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_from_file(path: PathBuf) -> Result<Self, CoconutError> {
|
||||
Ok(serde_json::from_str(&std::fs::read_to_string(path)?)?)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct State {
|
||||
persistent_state_path: PathBuf,
|
||||
announce_address: Url,
|
||||
dkg_keypair: DkgKeyPair,
|
||||
coconut_keypair: CoconutKeyPair,
|
||||
node_index: Option<NodeIndex>,
|
||||
dealers: BTreeMap<Addr, Result<DkgParticipant, ComplaintReason>>,
|
||||
receiver_index: Option<usize>,
|
||||
threshold: Option<Threshold>,
|
||||
recovered_vks: Vec<RecoveredVerificationKeys>,
|
||||
proposal_id: Option<u64>,
|
||||
voted_vks: bool,
|
||||
executed_proposal: bool,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new(
|
||||
persistent_state_path: PathBuf,
|
||||
persistent_state: PersistentState,
|
||||
announce_address: Url,
|
||||
dkg_keypair: DkgKeyPair,
|
||||
coconut_keypair: CoconutKeyPair,
|
||||
) -> Self {
|
||||
State {
|
||||
persistent_state_path,
|
||||
announce_address,
|
||||
dkg_keypair,
|
||||
coconut_keypair,
|
||||
node_index: persistent_state.node_index,
|
||||
dealers: persistent_state.dealers,
|
||||
receiver_index: persistent_state.receiver_index,
|
||||
threshold: persistent_state.threshold,
|
||||
recovered_vks: persistent_state.recovered_vks,
|
||||
proposal_id: persistent_state.proposal_id,
|
||||
voted_vks: persistent_state.voted_vks,
|
||||
executed_proposal: persistent_state.executed_proposal,
|
||||
node_index: None,
|
||||
dealers: BTreeMap::new(),
|
||||
receiver_index: None,
|
||||
threshold: None,
|
||||
recovered_vks: vec![],
|
||||
proposal_id: None,
|
||||
voted_vks: false,
|
||||
executed_proposal: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn persistent_state_path(&self) -> PathBuf {
|
||||
self.persistent_state_path.clone()
|
||||
}
|
||||
|
||||
pub fn announce_address(&self) -> &Url {
|
||||
&self.announce_address
|
||||
}
|
||||
|
||||
@@ -249,7 +249,6 @@ pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::coconut::dkg::dealing::dealing_exchange;
|
||||
use crate::coconut::dkg::public_key::public_key_submission;
|
||||
use crate::coconut::dkg::state::PersistentState;
|
||||
use crate::coconut::tests::DummyClient;
|
||||
use crate::coconut::KeyPair;
|
||||
use coconut_dkg_common::dealer::DealerDetails;
|
||||
@@ -260,7 +259,6 @@ pub(crate) mod tests {
|
||||
use rand::Rng;
|
||||
use std::collections::HashMap;
|
||||
use std::env::temp_dir;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use url::Url;
|
||||
@@ -291,8 +289,6 @@ pub(crate) mod tests {
|
||||
);
|
||||
let keypair = DkgKeyPair::new(¶ms, OsRng);
|
||||
let state = State::new(
|
||||
PathBuf::default(),
|
||||
PersistentState::default(),
|
||||
Url::parse("localhost:8000").unwrap(),
|
||||
keypair,
|
||||
KeyPair::new(),
|
||||
|
||||
@@ -23,9 +23,6 @@ pub enum CoconutError {
|
||||
#[error("{0}")]
|
||||
IOError(#[from] std::io::Error),
|
||||
|
||||
#[error("{0}")]
|
||||
SerdeJsonError(#[from] serde_json::Error),
|
||||
|
||||
#[error("Could not parse Ed25519 data")]
|
||||
Ed25519ParseError(#[from] Ed25519RecoveryError),
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::template::config_template;
|
||||
use config::defaults::mainnet::MIXNET_CONTRACT_ADDRESS;
|
||||
use config::defaults::DEFAULT_VALIDATOR_API_PORT;
|
||||
use config::NymConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -120,7 +119,7 @@ impl Default for Base {
|
||||
id: String::default(),
|
||||
local_validator: default_validator,
|
||||
announce_address: default_announce_address,
|
||||
mixnet_contract_address: MIXNET_CONTRACT_ADDRESS.to_string(),
|
||||
mixnet_contract_address: String::default(),
|
||||
mnemonic: "exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day".to_string(),
|
||||
}
|
||||
}
|
||||
@@ -283,9 +282,6 @@ pub struct CoconutSigner {
|
||||
/// Specifies whether rewarding service is enabled in this process.
|
||||
enabled: bool,
|
||||
|
||||
/// Path to a JSON file where state is persisted between different stages of DKG.
|
||||
dkg_persistent_state_path: PathBuf,
|
||||
|
||||
/// Path to the coconut verification key.
|
||||
verification_key_path: PathBuf,
|
||||
|
||||
@@ -303,7 +299,6 @@ pub struct CoconutSigner {
|
||||
}
|
||||
|
||||
impl CoconutSigner {
|
||||
pub const DKG_PERSISTENT_STATE_FILE: &'static str = "dkg_persistent_state.json";
|
||||
pub const DKG_DECRYPTION_KEY_FILE: &'static str = "dkg_decryption_key.pem";
|
||||
pub const DKG_PUBLIC_KEY_WITH_PROOF_FILE: &'static str = "dkg_public_key_with_proof.pem";
|
||||
pub const COCONUT_VERIFICATION_KEY_FILE: &'static str = "coconut_verification_key.pem";
|
||||
@@ -317,10 +312,6 @@ impl CoconutSigner {
|
||||
Config::default_data_directory(None).join(Self::COCONUT_SECRET_KEY_FILE)
|
||||
}
|
||||
|
||||
fn default_dkg_persistent_state_path() -> PathBuf {
|
||||
Config::default_data_directory(None).join(Self::DKG_PERSISTENT_STATE_FILE)
|
||||
}
|
||||
|
||||
fn default_dkg_decryption_key_path() -> PathBuf {
|
||||
Config::default_data_directory(None).join(Self::DKG_DECRYPTION_KEY_FILE)
|
||||
}
|
||||
@@ -334,7 +325,6 @@ impl Default for CoconutSigner {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: Default::default(),
|
||||
dkg_persistent_state_path: CoconutSigner::default_dkg_persistent_state_path(),
|
||||
verification_key_path: CoconutSigner::default_coconut_verification_key_path(),
|
||||
secret_key_path: CoconutSigner::default_coconut_secret_key_path(),
|
||||
decryption_key_path: CoconutSigner::default_dkg_decryption_key_path(),
|
||||
@@ -355,8 +345,6 @@ impl Config {
|
||||
Config::default_data_directory(Some(id)).join(NodeStatusAPI::DB_FILE);
|
||||
self.network_monitor.credentials_database_path =
|
||||
Config::default_data_directory(Some(id)).join(NetworkMonitor::DB_FILE);
|
||||
self.coconut_signer.dkg_persistent_state_path =
|
||||
Config::default_data_directory(Some(id)).join(CoconutSigner::DKG_PERSISTENT_STATE_FILE);
|
||||
self.coconut_signer.verification_key_path = Config::default_data_directory(Some(id))
|
||||
.join(CoconutSigner::COCONUT_VERIFICATION_KEY_FILE);
|
||||
self.coconut_signer.secret_key_path =
|
||||
@@ -521,11 +509,6 @@ impl Config {
|
||||
self.node_status_api.database_path.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
pub fn persistent_state_path(&self) -> PathBuf {
|
||||
self.coconut_signer.dkg_persistent_state_path.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
pub fn verification_key_path(&self) -> PathBuf {
|
||||
self.coconut_signer.verification_key_path.clone()
|
||||
|
||||
Reference in New Issue
Block a user