Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Clients: save init results to JSON #1865

Merged
merged 4 commits into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.lock

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

45 changes: 41 additions & 4 deletions clients/client-core/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

//! Collection of initialization steps used by client implementations

use std::{sync::Arc, time::Duration};
use std::{fmt::Display, sync::Arc, time::Duration};

use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
Expand All @@ -14,6 +14,7 @@ use nymsphinx::addressing::nodes::NodeIdentity;
use rand::rngs::OsRng;
use rand::seq::SliceRandom;
use rand::thread_rng;
use serde::Serialize;
use tap::TapFallible;
use topology::{filter::VersionFilterable, gateway};
use url::Url;
Expand All @@ -24,6 +25,43 @@ use crate::{
error::ClientCoreError,
};

#[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)
}
}

pub async fn query_gateway_details(
validator_servers: Vec<Url>,
chosen_gateway_id: Option<&str>,
Expand Down Expand Up @@ -102,7 +140,7 @@ async fn register_with_gateway(
Ok(shared_keys)
}

pub fn show_address<T>(config: &Config<T>) -> Result<(), ClientCoreError>
pub fn get_client_address<T>(config: &Config<T>) -> Result<Recipient, ClientCoreError>
where
T: config::NymConfig,
{
Expand Down Expand Up @@ -142,6 +180,5 @@ where
NodeIdentity::from_base58_string(config.get_gateway_id())?,
);

println!("\nThe address of this client is: {}", client_recipient);
Ok(())
Ok(client_recipient)
}
3 changes: 2 additions & 1 deletion clients/native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ 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
Expand All @@ -51,7 +53,6 @@ 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"]
Expand Down
52 changes: 50 additions & 2 deletions clients/native/src/commands/init.rs
Original file line number Diff line number Diff line change
@@ -1,9 +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 crate::{
client::config::Config,
Expand Down Expand Up @@ -55,6 +59,10 @@ 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 {
Expand All @@ -73,6 +81,29 @@ 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 {
pub 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) {
println!("Initialising client...");

Expand Down Expand Up @@ -126,10 +157,27 @@ pub(crate) async fn execute(args: &Init) {
);
println!("Client configuration completed.");

client_core::init::show_address(config.get_base()).unwrap_or_else(|err| {
eprintln!("Failed to show address\nError: {err}");
let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| {
eprintln!("Failed to get address\nError: {err}");
std::process::exit(1)
});

println!("\nThe address of this client is: {}\n", address);

let init_results = InitResults::new(&config, &address);
println!("{}", init_results);

// Output summary to a json file, if specified
if args.output_json {
let output_file = "client_init_results.json";
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),
}
}
}

async fn setup_gateway(
Expand Down
3 changes: 2 additions & 1 deletion clients/socks5/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ 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"
snafu = "0.6"
tap = "1.0.1"
thiserror = "1.0.34"
tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
url = "2.2"
Expand All @@ -46,7 +48,6 @@ 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"]
Expand Down
54 changes: 51 additions & 3 deletions clients/socks5/src/commands/init.rs
Original file line number Diff line number Diff line change
@@ -1,9 +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 crate::{
client::config::Config,
Expand Down Expand Up @@ -55,6 +59,10 @@ 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 {
Expand All @@ -71,6 +79,29 @@ 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 {
pub 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) {
println!("Initialising client...");

Expand Down Expand Up @@ -123,12 +154,29 @@ pub(crate) async fn execute(args: &Init) {
"Gateway listener: {}",
config.get_base().get_gateway_listener()
);
println!("Client configuration completed.");
println!("Client configuration completed.\n");

client_core::init::show_address(config.get_base()).unwrap_or_else(|err| {
eprintln!("Failed to show address\nError: {err}");
let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| {
eprintln!("Failed to get address\nError: {err}");
std::process::exit(1)
});

let init_results = InitResults::new(&config, &address);
println!("{}", init_results);

// Output summary to a json file, if specified
if args.output_json {
let output_file = "socks5_client_init_results.json";
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),
}
}

println!("\nThe address of this client is: {}\n", address);
}

async fn setup_gateway(
Expand Down
7 changes: 4 additions & 3 deletions nym-connect/Cargo.lock

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

3 changes: 2 additions & 1 deletion nym-connect/src-tauri/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
);
log::info!("Client configuration completed.");

client_core::init::show_address(config.get_base())?;
let address = client_core::init::get_client_address(config.get_base())?;
println!("\nThe address of this client is: {}\n", address);
Ok(())
}

Expand Down