native client config revamping
This commit is contained in:
@@ -1,25 +1,26 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::template::config_template;
|
||||
use crate::client::config::template::CONFIG_TEMPLATE;
|
||||
use nym_client_core::config::disk_persistence::CommonClientPathfinder;
|
||||
use nym_client_core::config::ClientCoreConfigTrait;
|
||||
use nym_config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
|
||||
use nym_config::{
|
||||
must_get_home, NymConfig, OptionalSet, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME,
|
||||
DEFAULT_DATA_DIR, NYM_DIR,
|
||||
define_optional_set_inner, must_get_home, read_config_from_toml_file,
|
||||
save_formatted_config_to_file, NymConfigTemplate, OptionalSet, DEFAULT_CONFIG_DIR,
|
||||
DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::io;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub use nym_client_core::config::Config as BaseConfig;
|
||||
pub use nym_client_core::config::MISSING_VALUE;
|
||||
pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig};
|
||||
|
||||
pub mod old_config_v1_1_13;
|
||||
pub mod old_config_v1_1_19;
|
||||
mod template;
|
||||
|
||||
const DEFAULT_CLIENTS_DIR: &str = "clients";
|
||||
@@ -58,8 +59,7 @@ impl SocketType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct Config {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseConfig,
|
||||
@@ -71,6 +71,12 @@ pub struct Config {
|
||||
pub logging: Logging,
|
||||
}
|
||||
|
||||
impl NymConfigTemplate for Config {
|
||||
fn template() -> &'static str {
|
||||
CONFIG_TEMPLATE
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
||||
Config {
|
||||
@@ -81,8 +87,21 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig {
|
||||
self.base.get_gateway_endpoint()
|
||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
read_config_from_toml_file(path)
|
||||
}
|
||||
|
||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
||||
Self::read_from_toml_file(default_config_filepath(id))
|
||||
}
|
||||
|
||||
pub fn default_location(&self) -> PathBuf {
|
||||
default_config_filepath(&self.base.client.id)
|
||||
}
|
||||
|
||||
pub fn save_to_default_location(&self) -> io::Result<()> {
|
||||
let config_save_location: PathBuf = self.default_location();
|
||||
save_formatted_config_to_file(self, config_save_location)
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> bool {
|
||||
@@ -114,80 +133,53 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
// getters
|
||||
pub fn get_config_file_save_location(&self) -> PathBuf {
|
||||
self.config_directory().join(Self::config_file_name())
|
||||
// poor man's 'builder' method
|
||||
pub fn with_base<F, T>(mut self, f: F, val: T) -> Self
|
||||
where
|
||||
F: Fn(BaseConfig, T) -> BaseConfig,
|
||||
{
|
||||
self.base = f(self.base, val);
|
||||
self
|
||||
}
|
||||
|
||||
// pub fn get_base(&self) -> &BaseConfig<Self> {
|
||||
// &self.base
|
||||
// }
|
||||
//
|
||||
// pub fn get_base_mut(&mut self) -> &mut BaseConfig<Self> {
|
||||
// &mut self.base
|
||||
// }
|
||||
|
||||
pub fn get_debug_settings(&self) -> &DebugConfig {
|
||||
self.get_base().get_debug_config()
|
||||
// helper methods to use `OptionalSet` trait. Those are defined due to very... ehm. 'specific' structure of this config
|
||||
// (plz, lets refactor it)
|
||||
pub fn with_optional_ext<F, T>(mut self, f: F, val: Option<T>) -> Self
|
||||
where
|
||||
F: Fn(BaseConfig, T) -> BaseConfig,
|
||||
{
|
||||
self.base = self.base.with_optional(f, val);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_socket_type(&self) -> SocketType {
|
||||
self.socket.socket_type
|
||||
pub fn with_optional_env_ext<F, T>(mut self, f: F, val: Option<T>, env_var: &str) -> Self
|
||||
where
|
||||
F: Fn(BaseConfig, T) -> BaseConfig,
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: Debug,
|
||||
{
|
||||
self.base = self.base.with_optional_env(f, val, env_var);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_listening_ip(&self) -> IpAddr {
|
||||
self.socket.host
|
||||
pub fn with_optional_custom_env_ext<F, T, G>(
|
||||
mut self,
|
||||
f: F,
|
||||
val: Option<T>,
|
||||
env_var: &str,
|
||||
parser: G,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn(BaseConfig, T) -> BaseConfig,
|
||||
G: Fn(&str) -> T,
|
||||
{
|
||||
self.base = self.base.with_optional_custom_env(f, val, env_var, parser);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_listening_port(&self) -> u16 {
|
||||
self.socket.listening_port
|
||||
}
|
||||
|
||||
// // poor man's 'builder' method
|
||||
// pub fn with_base<F, T>(mut self, f: F, val: T) -> Self
|
||||
// where
|
||||
// F: Fn(BaseConfig<Self>, T) -> BaseConfig<Self>,
|
||||
// {
|
||||
// self.base = f(self.base, val);
|
||||
// self
|
||||
// }
|
||||
//
|
||||
// // helper methods to use `OptionalSet` trait. Those are defined due to very... ehm. 'specific' structure of this config
|
||||
// // (plz, lets refactor it)
|
||||
// pub fn with_optional_ext<F, T>(mut self, f: F, val: Option<T>) -> Self
|
||||
// where
|
||||
// F: Fn(BaseConfig<Self>, T) -> BaseConfig<Self>,
|
||||
// {
|
||||
// self.base = self.base.with_optional(f, val);
|
||||
// self
|
||||
// }
|
||||
//
|
||||
// pub fn with_optional_env_ext<F, T>(mut self, f: F, val: Option<T>, env_var: &str) -> Self
|
||||
// where
|
||||
// F: Fn(BaseConfig<Self>, T) -> BaseConfig<Self>,
|
||||
// T: FromStr,
|
||||
// <T as FromStr>::Err: Debug,
|
||||
// {
|
||||
// self.base = self.base.with_optional_env(f, val, env_var);
|
||||
// self
|
||||
// }
|
||||
//
|
||||
// pub fn with_optional_custom_env_ext<F, T, G>(
|
||||
// mut self,
|
||||
// f: F,
|
||||
// val: Option<T>,
|
||||
// env_var: &str,
|
||||
// parser: G,
|
||||
// ) -> Self
|
||||
// where
|
||||
// F: Fn(BaseConfig<Self>, T) -> BaseConfig<Self>,
|
||||
// G: Fn(&str) -> T,
|
||||
// {
|
||||
// self.base = self.base.with_optional_custom_env(f, val, env_var, parser);
|
||||
// self
|
||||
// }
|
||||
}
|
||||
|
||||
// define_optional_set_inner!(Config, base, BaseConfig);
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Logging {}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
use crate::client::config::{Config, Socket};
|
||||
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
||||
use nym_config::NymConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -16,45 +15,46 @@ pub struct OldConfigV1_1_13 {
|
||||
socket: Socket,
|
||||
}
|
||||
|
||||
impl NymConfig for OldConfigV1_1_13 {
|
||||
fn template() -> &'static str {
|
||||
// not intended to be used
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn default_root_directory() -> PathBuf {
|
||||
dirs::home_dir()
|
||||
.expect("Failed to evaluate $HOME value")
|
||||
.join(".nym")
|
||||
.join("clients")
|
||||
}
|
||||
|
||||
fn try_default_root_directory() -> Option<PathBuf> {
|
||||
dirs::home_dir().map(|path| path.join(".nym").join("clients"))
|
||||
}
|
||||
|
||||
fn root_directory(&self) -> PathBuf {
|
||||
self.base.client.nym_root_directory.clone()
|
||||
}
|
||||
|
||||
fn config_directory(&self) -> PathBuf {
|
||||
self.root_directory()
|
||||
.join(&self.base.client.id)
|
||||
.join("config")
|
||||
}
|
||||
|
||||
fn data_directory(&self) -> PathBuf {
|
||||
self.root_directory()
|
||||
.join(&self.base.client.id)
|
||||
.join("data")
|
||||
}
|
||||
}
|
||||
// impl NymConfig for OldConfigV1_1_13 {
|
||||
// fn template() -> &'static str {
|
||||
// // not intended to be used
|
||||
// unimplemented!()
|
||||
// }
|
||||
//
|
||||
// fn default_root_directory() -> PathBuf {
|
||||
// dirs::home_dir()
|
||||
// .expect("Failed to evaluate $HOME value")
|
||||
// .join(".nym")
|
||||
// .join("clients")
|
||||
// }
|
||||
//
|
||||
// fn try_default_root_directory() -> Option<PathBuf> {
|
||||
// dirs::home_dir().map(|path| path.join(".nym").join("clients"))
|
||||
// }
|
||||
//
|
||||
// fn root_directory(&self) -> PathBuf {
|
||||
// self.base.client.nym_root_directory.clone()
|
||||
// }
|
||||
//
|
||||
// fn config_directory(&self) -> PathBuf {
|
||||
// self.root_directory()
|
||||
// .join(&self.base.client.id)
|
||||
// .join("config")
|
||||
// }
|
||||
//
|
||||
// fn data_directory(&self) -> PathBuf {
|
||||
// self.root_directory()
|
||||
// .join(&self.base.client.id)
|
||||
// .join("data")
|
||||
// }
|
||||
// }
|
||||
|
||||
impl From<OldConfigV1_1_13> for Config {
|
||||
fn from(value: OldConfigV1_1_13) -> Self {
|
||||
Config {
|
||||
base: value.base.into(),
|
||||
socket: value.socket,
|
||||
}
|
||||
todo!()
|
||||
// Config {
|
||||
// base: value.base.into(),
|
||||
// socket: value.socket,
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub(crate) fn config_template() -> &'static str {
|
||||
pub(crate) const CONFIG_TEMPLATE: &str =
|
||||
// While using normal toml marshalling would have been way simpler with less overhead,
|
||||
// I think it's useful to have comments attached to the saved config file to explain behaviour of
|
||||
// particular fields.
|
||||
@@ -120,5 +120,4 @@ average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'
|
||||
[debug.cover_traffic]
|
||||
loop_cover_traffic_average_delay = '{{ debug.cover_traffic.loop_cover_traffic_average_delay }}'
|
||||
|
||||
"#
|
||||
}
|
||||
"#;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::Config;
|
||||
@@ -50,11 +50,11 @@ impl SocketClient {
|
||||
config: &Config,
|
||||
) -> BandwidthController<Client<QueryNyxdClient>, PersistentStorage> {
|
||||
let storage = nym_credential_storage::initialise_persistent_storage(
|
||||
config.get_base().get_database_path(),
|
||||
&config.paths.credentials_database,
|
||||
)
|
||||
.await;
|
||||
|
||||
create_bandwidth_controller(config.get_base(), storage)
|
||||
create_bandwidth_controller(&config.base, storage)
|
||||
}
|
||||
|
||||
fn start_websocket_listener(
|
||||
@@ -93,7 +93,7 @@ impl SocketClient {
|
||||
Some(packet_type),
|
||||
);
|
||||
|
||||
websocket::Listener::new(config.get_listening_ip(), config.get_listening_port())
|
||||
websocket::Listener::new(config.socket.host, config.socket.listening_port)
|
||||
.start(websocket_handler, shutdown);
|
||||
}
|
||||
|
||||
@@ -107,26 +107,25 @@ impl SocketClient {
|
||||
}
|
||||
|
||||
fn key_store(&self) -> OnDiskKeys {
|
||||
let pathfinder = ClientKeysPathfinder::new_from_config(self.config.get_base());
|
||||
OnDiskKeys::new(pathfinder)
|
||||
OnDiskKeys::new(self.config.paths.key_pathfinder.clone())
|
||||
}
|
||||
|
||||
// TODO: see if this could also be shared with socks5 client / nym-sdk maybe
|
||||
async fn create_base_client_builder(&self) -> Result<NativeClientBuilder, ClientError> {
|
||||
// don't create bandwidth controller if credentials are disabled
|
||||
let bandwidth_controller = if self.config.get_base().get_disabled_credentials_mode() {
|
||||
let bandwidth_controller = if self.config.base.client.disabled_credentials_mode {
|
||||
None
|
||||
} else {
|
||||
Some(Self::create_bandwidth_controller(&self.config).await)
|
||||
};
|
||||
|
||||
let base_client = BaseClientBuilder::new_from_base_config(
|
||||
self.config.get_base(),
|
||||
&self.config.base,
|
||||
self.key_store(),
|
||||
bandwidth_controller,
|
||||
non_wasm_helpers::setup_fs_reply_surb_backend(
|
||||
self.config.get_base().get_reply_surb_database_path(),
|
||||
&self.config.get_debug_settings().reply_surbs,
|
||||
&self.config.paths.reply_surb_database_path,
|
||||
&self.config.base.debug.reply_surbs,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
@@ -135,7 +134,7 @@ impl SocketClient {
|
||||
}
|
||||
|
||||
pub async fn start_socket(self) -> Result<TaskManager, ClientError> {
|
||||
if !self.config.get_socket_type().is_websocket() {
|
||||
if !self.config.socket.socket_type.is_websocket() {
|
||||
return Err(ClientError::InvalidSocketMode);
|
||||
}
|
||||
|
||||
@@ -164,7 +163,7 @@ impl SocketClient {
|
||||
}
|
||||
|
||||
pub async fn start_direct(self) -> Result<DirectClient, ClientError> {
|
||||
if self.config.get_socket_type().is_websocket() {
|
||||
if self.config.socket.socket_type.is_websocket() {
|
||||
return Err(ClientError::InvalidSocketMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::default_config_filepath;
|
||||
use crate::commands::try_upgrade_v1_1_13_config;
|
||||
use crate::{
|
||||
client::config::Config,
|
||||
@@ -10,7 +11,6 @@ use crate::{
|
||||
use clap::Args;
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||
use nym_config::NymConfig;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use serde::Serialize;
|
||||
@@ -97,15 +97,15 @@ impl From<Init> for OverrideConfig {
|
||||
pub struct InitResults {
|
||||
#[serde(flatten)]
|
||||
client_core: nym_client_core::init::InitResults,
|
||||
client_listening_port: String,
|
||||
client_listening_port: u16,
|
||||
client_address: String,
|
||||
}
|
||||
|
||||
impl InitResults {
|
||||
fn new(config: &Config, address: &Recipient) -> Self {
|
||||
Self {
|
||||
client_core: nym_client_core::init::InitResults::new(config.get_base(), address),
|
||||
client_listening_port: config.get_listening_port().to_string(),
|
||||
client_core: nym_client_core::init::InitResults::new(&config.base, address),
|
||||
client_listening_port: config.socket.listening_port,
|
||||
client_address: address.to_string(),
|
||||
}
|
||||
}
|
||||
@@ -124,13 +124,15 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
||||
|
||||
let id = &args.id;
|
||||
|
||||
let already_init = Config::default_config_file_path(id).exists();
|
||||
if already_init {
|
||||
let already_init = if default_config_filepath(&id).exists() {
|
||||
// in case we're using old config, try to upgrade it
|
||||
// (if we're using the current version, it's a no-op)
|
||||
try_upgrade_v1_1_13_config(id)?;
|
||||
eprintln!("Client \"{id}\" was already initialised before");
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Usually you only register with the gateway on the first init, however you can force
|
||||
// re-registering if wanted.
|
||||
@@ -152,42 +154,37 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
||||
|
||||
// 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 key_store = OnDiskKeys::from_config(config.get_base());
|
||||
let gateway = nym_client_core::init::setup_gateway_from_config::<Config, _, _>(
|
||||
let key_store = OnDiskKeys::new(config.paths.key_pathfinder.clone());
|
||||
let gateway = nym_client_core::init::setup_gateway_from_config::<_>(
|
||||
&key_store,
|
||||
register_gateway,
|
||||
user_chosen_gateway_id,
|
||||
config.get_base(),
|
||||
&config.base,
|
||||
args.latency_based_selection,
|
||||
)
|
||||
.await
|
||||
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
||||
|
||||
config.get_base_mut().set_gateway_endpoint(gateway);
|
||||
config.base.set_gateway_endpoint(gateway);
|
||||
|
||||
config.save_to_file(None).tap_err(|_| {
|
||||
let config_save_location = config.default_location();
|
||||
config.save_to_default_location().tap_err(|_| {
|
||||
log::error!("Failed to save the config file");
|
||||
})?;
|
||||
eprintln!(
|
||||
"Saved configuration file to {}",
|
||||
config_save_location.display()
|
||||
);
|
||||
|
||||
print_saved_config(&config);
|
||||
let address = nym_client_core::init::get_client_address_from_stored_ondisk_keys(
|
||||
&config.paths.key_pathfinder,
|
||||
&config.base.client.gateway_endpoint,
|
||||
)?;
|
||||
|
||||
eprintln!("Client configuration completed.\n");
|
||||
|
||||
let address =
|
||||
nym_client_core::init::get_client_address_from_stored_ondisk_keys(config.get_base())?;
|
||||
let init_results = InitResults::new(&config, &address);
|
||||
println!("{}", args.output.format(&init_results));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_saved_config(config: &Config) {
|
||||
let config_save_location = config.get_config_file_save_location();
|
||||
eprintln!("Saved configuration file to {config_save_location:?}");
|
||||
eprintln!("Using gateway: {}", config.get_base().get_gateway_id());
|
||||
log::debug!("Gateway id: {}", config.get_base().get_gateway_id());
|
||||
log::debug!("Gateway owner: {}", config.get_base().get_gateway_owner());
|
||||
log::debug!(
|
||||
"Gateway listener: {}",
|
||||
config.get_base().get_gateway_listener()
|
||||
);
|
||||
eprintln!("Client configuration completed.\n");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use lazy_static::lazy_static;
|
||||
use log::info;
|
||||
use nym_bin_common::build_information::BinaryBuildInformation;
|
||||
use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||
use nym_config::{NymConfig, OptionalSet};
|
||||
use nym_config::OptionalSet;
|
||||
use std::error::Error;
|
||||
use std::net::IpAddr;
|
||||
|
||||
@@ -105,17 +105,18 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
}
|
||||
|
||||
fn try_upgrade_v1_1_13_config(id: &str) -> std::io::Result<()> {
|
||||
// explicitly load it as v1.1.13 (which is incompatible with the current, i.e. 1.1.14+)
|
||||
let Ok(old_config) = OldConfigV1_1_13::load_from_file(id) else {
|
||||
// if we failed to load it, there might have been nothing to upgrade
|
||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
return Ok(());
|
||||
};
|
||||
info!("It seems the client is using <= v1.1.13 config template.");
|
||||
info!("It is going to get updated to the current specification.");
|
||||
|
||||
let updated: Config = old_config.into();
|
||||
updated.save_to_file(None)
|
||||
todo!()
|
||||
// // explicitly load it as v1.1.13 (which is incompatible with the current, i.e. 1.1.14+)
|
||||
// let Ok(old_config) = OldConfigV1_1_13::load_from_file(id) else {
|
||||
// // if we failed to load it, there might have been nothing to upgrade
|
||||
// // or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
// return Ok(());
|
||||
// };
|
||||
// info!("It seems the client is using <= v1.1.13 config template.");
|
||||
// info!("It is going to get updated to the current specification.");
|
||||
//
|
||||
// let updated: Config = old_config.into();
|
||||
// updated.save_to_file(None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -13,7 +13,6 @@ use crate::{
|
||||
use clap::Args;
|
||||
use log::*;
|
||||
use nym_bin_common::version_checker::is_minor_version_compatible;
|
||||
use nym_config::NymConfig;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
@@ -82,7 +81,7 @@ impl From<Run> for OverrideConfig {
|
||||
// network version. It might do so in the future.
|
||||
fn version_check(cfg: &Config) -> bool {
|
||||
let binary_version = env!("CARGO_PKG_VERSION");
|
||||
let config_version = cfg.get_base().get_version();
|
||||
let config_version = &cfg.base.client.version;
|
||||
if binary_version == config_version {
|
||||
true
|
||||
} else {
|
||||
@@ -104,7 +103,7 @@ pub(crate) async fn execute(args: &Run) -> Result<(), Box<dyn Error + Send + Syn
|
||||
// (if we're using the current version, it's a no-op)
|
||||
try_upgrade_v1_1_13_config(id)?;
|
||||
|
||||
let mut config = match Config::load_from_file(id) {
|
||||
let mut config = match Config::read_from_default_path(id) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(err) => {
|
||||
error!("Failed to load config for {}. Are you sure you have run `init` before? (Error was: {err})", id);
|
||||
@@ -119,10 +118,6 @@ pub(crate) async fn execute(args: &Run) -> Result<(), Box<dyn Error + Send + Syn
|
||||
let override_config_fields = OverrideConfig::from(args.clone());
|
||||
config = override_config(config, override_config_fields);
|
||||
|
||||
if config.get_base_mut().set_empty_fields_to_defaults() {
|
||||
warn!("some of the core config options were left unset. the default values are going to get used instead.");
|
||||
}
|
||||
|
||||
if !version_check(&config) {
|
||||
error!("failed the local version check");
|
||||
return Err(Box::new(ClientError::FailedLocalVersionCheck));
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::config::{Config, MISSING_VALUE};
|
||||
|
||||
use nym_bin_common::version_checker::Version;
|
||||
use nym_config::NymConfig;
|
||||
|
||||
use crate::client::config::Config;
|
||||
use clap::Args;
|
||||
use nym_bin_common::version_checker::Version;
|
||||
use std::fmt::Display;
|
||||
use std::process;
|
||||
|
||||
@@ -40,6 +37,12 @@ fn unsupported_upgrade(current_version: &Version, config_version: &Version) -> !
|
||||
process::exit(1)
|
||||
}
|
||||
|
||||
fn unimplemented_upgrade(current_version: &Version, config_version: &Version) -> ! {
|
||||
eprintln!("Cannot perform upgrade from {config_version} to {current_version} as it hasn't been implemented yet");
|
||||
todo!();
|
||||
process::exit(1)
|
||||
}
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
pub(crate) struct Upgrade {
|
||||
/// Id of the nym-client we want to upgrade
|
||||
@@ -48,7 +51,7 @@ pub(crate) struct Upgrade {
|
||||
}
|
||||
|
||||
fn parse_config_version(config: &Config) -> Version {
|
||||
let version = Version::parse(config.get_base().get_version()).unwrap_or_else(|err| {
|
||||
let version = Version::parse(&config.base.client.version).unwrap_or_else(|err| {
|
||||
eprintln!("failed to parse client version! - {err}");
|
||||
process::exit(1)
|
||||
});
|
||||
@@ -77,35 +80,6 @@ fn parse_package_version() -> Version {
|
||||
version
|
||||
}
|
||||
|
||||
fn minor_0_12_upgrade(
|
||||
mut config: Config,
|
||||
_matches: &Upgrade,
|
||||
config_version: &Version,
|
||||
package_version: &Version,
|
||||
) -> Config {
|
||||
let to_version = if package_version.major == 0 && package_version.minor == 12 {
|
||||
package_version.clone()
|
||||
} else {
|
||||
Version::new(0, 12, 0)
|
||||
};
|
||||
|
||||
print_start_upgrade(config_version, &to_version);
|
||||
|
||||
config
|
||||
.get_base_mut()
|
||||
.set_custom_version(to_version.to_string().as_ref());
|
||||
|
||||
config.save_to_file(None).unwrap_or_else(|err| {
|
||||
eprintln!("failed to overwrite config file! - {err}");
|
||||
print_failed_upgrade(config_version, &to_version);
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
print_successful_upgrade(config_version, to_version);
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
fn do_upgrade(mut config: Config, args: &Upgrade, package_version: &Version) {
|
||||
loop {
|
||||
let config_version = parse_config_version(&config);
|
||||
@@ -116,9 +90,10 @@ fn do_upgrade(mut config: Config, args: &Upgrade, package_version: &Version) {
|
||||
}
|
||||
|
||||
config = match config_version.major {
|
||||
0 => match config_version.minor {
|
||||
9 | 10 => outdated_upgrade(&config_version, package_version),
|
||||
11 => minor_0_12_upgrade(config, args, &config_version, package_version),
|
||||
0 => outdated_upgrade(&config_version, package_version),
|
||||
1 => match config_version.minor {
|
||||
n if n <= 13 => outdated_upgrade(&config_version, package_version),
|
||||
n if n > 13 && n < 19 => unimplemented_upgrade(&config_version, package_version),
|
||||
_ => unsupported_upgrade(&config_version, package_version),
|
||||
},
|
||||
_ => unsupported_upgrade(&config_version, package_version),
|
||||
@@ -131,12 +106,12 @@ pub(crate) fn execute(args: &Upgrade) {
|
||||
|
||||
let id = &args.id;
|
||||
|
||||
let existing_config = Config::load_from_file(id).unwrap_or_else(|err| {
|
||||
let existing_config = Config::read_from_default_path(id).unwrap_or_else(|err| {
|
||||
eprintln!("failed to load existing config file! - {err}");
|
||||
process::exit(1)
|
||||
});
|
||||
|
||||
if existing_config.get_base().get_version() == MISSING_VALUE {
|
||||
if existing_config.base.client.version.is_empty() {
|
||||
eprintln!("the existing configuration file does not seem to contain version number.");
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
@@ -176,15 +176,15 @@ where
|
||||
C: DkgQueryClient + Send + Sync + 'static,
|
||||
{
|
||||
// TODO: combine all storages
|
||||
pub fn new_from_base_config<T>(
|
||||
base_config: &'a Config<T>,
|
||||
pub fn new_from_base_config(
|
||||
base_config: &'a Config,
|
||||
key_store: S::KeyStore,
|
||||
bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>,
|
||||
reply_storage_backend: S::ReplyStore,
|
||||
) -> BaseClientBuilder<'a, C, S> {
|
||||
BaseClientBuilder {
|
||||
gateway_config: base_config.get_gateway_endpoint_config(),
|
||||
debug_config: base_config.get_debug_config(),
|
||||
debug_config: &base_config.debug,
|
||||
disabled_credentials: base_config.get_disabled_credentials_mode(),
|
||||
nym_api_endpoints: base_config.get_nym_api_endpoints(),
|
||||
bandwidth_controller,
|
||||
|
||||
@@ -101,8 +101,8 @@ pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_bandwidth_controller<T, St: CredentialStorage>(
|
||||
config: &Config<T>,
|
||||
pub fn create_bandwidth_controller<St: CredentialStorage>(
|
||||
config: &Config,
|
||||
storage: St,
|
||||
) -> BandwidthController<Client<QueryNyxdClient>, St> {
|
||||
let nyxd_url = config
|
||||
|
||||
@@ -63,49 +63,49 @@ impl ClientKeysPathfinder {
|
||||
}
|
||||
|
||||
pub fn any_file_exists(&self) -> bool {
|
||||
matches!(self.identity_public_key.try_exists(), Ok(true))
|
||||
|| matches!(self.identity_private_key.try_exists(), Ok(true))
|
||||
|| matches!(self.encryption_public_key.try_exists(), Ok(true))
|
||||
|| matches!(self.encryption_private_key.try_exists(), Ok(true))
|
||||
|| matches!(self.gateway_shared_key.try_exists(), Ok(true))
|
||||
|| matches!(self.ack_key.try_exists(), Ok(true))
|
||||
matches!(self.public_identity_key_file.try_exists(), Ok(true))
|
||||
|| matches!(self.private_identity_key_file.try_exists(), Ok(true))
|
||||
|| matches!(self.public_encryption_key_file.try_exists(), Ok(true))
|
||||
|| matches!(self.private_encryption_key_file.try_exists(), Ok(true))
|
||||
|| matches!(self.gateway_shared_key_file.try_exists(), Ok(true))
|
||||
|| matches!(self.ack_key_file.try_exists(), Ok(true))
|
||||
}
|
||||
|
||||
pub fn any_file_exists_and_return(&self) -> Option<PathBuf> {
|
||||
file_exists(&self.identity_public_key)
|
||||
.or_else(|| file_exists(&self.identity_private_key))
|
||||
.or_else(|| file_exists(&self.encryption_public_key))
|
||||
.or_else(|| file_exists(&self.encryption_private_key))
|
||||
.or_else(|| file_exists(&self.gateway_shared_key))
|
||||
.or_else(|| file_exists(&self.ack_key))
|
||||
file_exists(&self.public_identity_key_file)
|
||||
.or_else(|| file_exists(&self.private_identity_key_file))
|
||||
.or_else(|| file_exists(&self.public_encryption_key_file))
|
||||
.or_else(|| file_exists(&self.private_encryption_key_file))
|
||||
.or_else(|| file_exists(&self.gateway_shared_key_file))
|
||||
.or_else(|| file_exists(&self.ack_key_file))
|
||||
}
|
||||
|
||||
pub fn gateway_key_file_exists(&self) -> bool {
|
||||
matches!(self.gateway_shared_key.try_exists(), Ok(true))
|
||||
matches!(self.gateway_shared_key_file.try_exists(), Ok(true))
|
||||
}
|
||||
|
||||
pub fn private_identity_key(&self) -> &Path {
|
||||
&self.identity_private_key
|
||||
&self.private_identity_key_file
|
||||
}
|
||||
|
||||
pub fn public_identity_key(&self) -> &Path {
|
||||
&self.identity_public_key
|
||||
&self.public_identity_key_file
|
||||
}
|
||||
|
||||
pub fn private_encryption_key(&self) -> &Path {
|
||||
&self.encryption_private_key
|
||||
&self.private_encryption_key_file
|
||||
}
|
||||
|
||||
pub fn public_encryption_key(&self) -> &Path {
|
||||
&self.encryption_public_key
|
||||
&self.public_encryption_key_file
|
||||
}
|
||||
|
||||
pub fn gateway_shared_key(&self) -> &Path {
|
||||
&self.gateway_shared_key
|
||||
&self.gateway_shared_key_file
|
||||
}
|
||||
|
||||
pub fn ack_key(&self) -> &Path {
|
||||
&self.ack_key
|
||||
&self.ack_key_file
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6
|
||||
// 24 hours
|
||||
const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60);
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
pub client: Client,
|
||||
@@ -180,14 +180,6 @@ impl Config {
|
||||
pub fn get_gateway_endpoint_config(&self) -> &GatewayEndpointConfig {
|
||||
&self.client.gateway_endpoint
|
||||
}
|
||||
|
||||
pub fn get_database_path(&self) -> PathBuf {
|
||||
self.client.database_path.clone()
|
||||
}
|
||||
|
||||
pub fn get_reply_surb_database_path(&self) -> PathBuf {
|
||||
self.client.reply_surb_database_path.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
||||
@@ -281,7 +273,7 @@ impl Client {
|
||||
|
||||
Client {
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
id: "DEFAULT-CLIENT".to_string(),
|
||||
id: id.into(),
|
||||
disabled_credentials_mode: true,
|
||||
nyxd_urls,
|
||||
nym_api_urls,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::{
|
||||
Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, Logging,
|
||||
ReplySurbs, Topology, Traffic, DEFAULT_ACK_WAIT_ADDITION, DEFAULT_ACK_WAIT_MULTIPLIER,
|
||||
Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, ReplySurbs,
|
||||
Topology, Traffic, DEFAULT_ACK_WAIT_ADDITION, DEFAULT_ACK_WAIT_MULTIPLIER,
|
||||
DEFAULT_AVERAGE_PACKET_DELAY, DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
|
||||
DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE,
|
||||
DEFAULT_MAXIMUM_REPLY_KEY_AGE, DEFAULT_MAXIMUM_REPLY_SURB_AGE,
|
||||
@@ -13,12 +13,13 @@ use crate::config::{
|
||||
DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
||||
DEFAULT_TOPOLOGY_REFRESH_RATE, DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
|
||||
};
|
||||
use nym_config::NymConfig;
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::marker::PhantomData;
|
||||
use std::time::Duration;
|
||||
|
||||
// use nym_config::NymConfig;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ExtendedPacketSize {
|
||||
@@ -40,21 +41,22 @@ impl From<ExtendedPacketSize> for PacketSize {
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct OldConfigV1_1_13<T> {
|
||||
pub client: Client<T>,
|
||||
|
||||
#[serde(default)]
|
||||
logging: Logging,
|
||||
pub client: PhantomData<T>,
|
||||
// pub client: Client<T>,
|
||||
// #[serde(default)]
|
||||
// logging: Logging,
|
||||
#[serde(default)]
|
||||
debug: OldDebugConfigV1_1_13,
|
||||
}
|
||||
|
||||
impl<T: NymConfig> Default for OldConfigV1_1_13<T> {
|
||||
impl<T> Default for OldConfigV1_1_13<T> {
|
||||
fn default() -> Self {
|
||||
OldConfigV1_1_13 {
|
||||
client: Client::<T>::default(),
|
||||
logging: Default::default(),
|
||||
debug: Default::default(),
|
||||
}
|
||||
todo!()
|
||||
// OldConfigV1_1_13 {
|
||||
// client: Client::<T>::default(),
|
||||
// logging: Default::default(),
|
||||
// debug: Default::default(),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +127,6 @@ impl From<OldDebugConfigV1_1_13> for DebugConfig {
|
||||
.disable_main_poisson_packet_distribution,
|
||||
primary_packet_size: PacketSize::RegularPacket,
|
||||
secondary_packet_size: value.use_extended_packet_size.map(Into::into),
|
||||
packet_type: None,
|
||||
},
|
||||
cover_traffic: CoverTraffic {
|
||||
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
||||
@@ -192,30 +193,31 @@ impl Default for OldDebugConfigV1_1_13 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> From<OldConfigV1_1_13<T>> for Config<U> {
|
||||
impl<T> From<OldConfigV1_1_13<T>> for Config {
|
||||
fn from(value: OldConfigV1_1_13<T>) -> Self {
|
||||
Config {
|
||||
client: Client {
|
||||
version: value.client.version,
|
||||
id: value.client.id,
|
||||
disabled_credentials_mode: value.client.disabled_credentials_mode,
|
||||
nyxd_urls: value.client.nyxd_urls,
|
||||
nym_api_urls: value.client.nym_api_urls,
|
||||
private_identity_key_file: value.client.private_identity_key_file,
|
||||
public_identity_key_file: value.client.public_identity_key_file,
|
||||
private_encryption_key_file: value.client.private_encryption_key_file,
|
||||
public_encryption_key_file: value.client.public_encryption_key_file,
|
||||
gateway_shared_key_file: value.client.gateway_shared_key_file,
|
||||
ack_key_file: value.client.ack_key_file,
|
||||
gateway_endpoint: value.client.gateway_endpoint,
|
||||
database_path: value.client.database_path,
|
||||
reply_surb_database_path: value.client.reply_surb_database_path,
|
||||
nym_root_directory: value.client.nym_root_directory,
|
||||
super_struct: PhantomData,
|
||||
packet_type: Some(nym_sphinx::params::PacketType::Mix),
|
||||
},
|
||||
logging: value.logging,
|
||||
debug: value.debug.into(),
|
||||
}
|
||||
todo!()
|
||||
// Config {
|
||||
// client: Client {
|
||||
// version: value.client.version,
|
||||
// id: value.client.id,
|
||||
// disabled_credentials_mode: value.client.disabled_credentials_mode,
|
||||
// nyxd_urls: value.client.nyxd_urls,
|
||||
// nym_api_urls: value.client.nym_api_urls,
|
||||
// private_identity_key_file: value.client.private_identity_key_file,
|
||||
// public_identity_key_file: value.client.public_identity_key_file,
|
||||
// private_encryption_key_file: value.client.private_encryption_key_file,
|
||||
// public_encryption_key_file: value.client.public_encryption_key_file,
|
||||
// gateway_shared_key_file: value.client.gateway_shared_key_file,
|
||||
// ack_key_file: value.client.ack_key_file,
|
||||
// gateway_endpoint: value.client.gateway_endpoint,
|
||||
// database_path: value.client.database_path,
|
||||
// reply_surb_database_path: value.client.reply_surb_database_path,
|
||||
// nym_root_directory: value.client.nym_root_directory,
|
||||
//
|
||||
// super_struct: PhantomData,
|
||||
// },
|
||||
// logging: value.logging,
|
||||
// debug: value.debug.into(),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,13 +120,10 @@ pub struct InitResults {
|
||||
}
|
||||
|
||||
impl InitResults {
|
||||
pub fn new<T>(config: &Config<T>, address: &Recipient) -> Self
|
||||
where
|
||||
T: NymConfig,
|
||||
{
|
||||
pub fn new(config: &Config, address: &Recipient) -> Self {
|
||||
Self {
|
||||
version: config.get_version().to_string(),
|
||||
id: config.get_id(),
|
||||
version: config.client.version.clone(),
|
||||
id: config.client.id.clone(),
|
||||
identity_key: address.identity().to_base58_string(),
|
||||
encryption_key: address.encryption_key().to_base58_string(),
|
||||
gateway_id: config.get_gateway_id(),
|
||||
@@ -204,26 +201,22 @@ where
|
||||
/// b. Create a new gateway configuration but keep existing keys. This assumes that the caller
|
||||
/// knows what they are doing and that the keys match the requested gateway.
|
||||
/// c. Create a new gateway configuration with a newly registered gateway and keys.
|
||||
pub async fn setup_gateway_from_config<C, T, KSt>(
|
||||
pub async fn setup_gateway_from_config<KSt>(
|
||||
key_store: &KSt,
|
||||
register_gateway: bool,
|
||||
user_chosen_gateway_id: Option<identity::PublicKey>,
|
||||
config: &Config<T>,
|
||||
config: &Config,
|
||||
by_latency: bool,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError>
|
||||
where
|
||||
C: NymConfig + ClientCoreConfigTrait,
|
||||
T: NymConfig,
|
||||
KSt: KeyStore,
|
||||
<KSt as KeyStore>::StorageError: Send + Sync + 'static,
|
||||
{
|
||||
let id = config.get_id();
|
||||
|
||||
// If we are not going to register gateway, and an explicitly chosen gateway is not passed in,
|
||||
// load the existing configuration file
|
||||
if !register_gateway && user_chosen_gateway_id.is_none() {
|
||||
eprintln!("Not registering gateway, will reuse existing config and keys");
|
||||
return load_existing_gateway_config::<C>(&id);
|
||||
return Ok(config.client.gateway_endpoint.clone());
|
||||
}
|
||||
|
||||
let gateway_setup = GatewaySetup::new(
|
||||
@@ -264,25 +257,6 @@ where
|
||||
Ok(gateway)
|
||||
}
|
||||
|
||||
/// Read and reuse the existing gateway configuration from a file that was generate earlier.
|
||||
pub fn load_existing_gateway_config<T>(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError>
|
||||
where
|
||||
T: NymConfig + ClientCoreConfigTrait,
|
||||
{
|
||||
T::load_from_file(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 full client address from the client keys and the gateway identity
|
||||
pub fn get_client_address(
|
||||
key_manager: &KeyManager,
|
||||
@@ -299,40 +273,21 @@ pub fn get_client_address(
|
||||
|
||||
/// Get the client address by loading the keys from stored files.
|
||||
// TODO: rethink that sucker
|
||||
pub fn get_client_address_from_stored_ondisk_keys<T>(
|
||||
config: &Config<T>,
|
||||
) -> Result<Recipient, ClientCoreError>
|
||||
where
|
||||
T: nym_config::NymConfig,
|
||||
{
|
||||
fn load_identity_keys(
|
||||
pathfinder: &ClientKeysPathfinder,
|
||||
) -> Result<identity::KeyPair, ClientCoreError> {
|
||||
let identity_keypair: identity::KeyPair =
|
||||
nym_pemstore::load_keypair(&pathfinder.identity_key_pair_path())
|
||||
.tap_err(|_| log::error!("Failed to read stored identity key files"))?;
|
||||
Ok(identity_keypair)
|
||||
}
|
||||
|
||||
fn load_sphinx_keys(
|
||||
pathfinder: &ClientKeysPathfinder,
|
||||
) -> Result<encryption::KeyPair, ClientCoreError> {
|
||||
let sphinx_keypair: encryption::KeyPair =
|
||||
nym_pemstore::load_keypair(&pathfinder.encryption_key_pair_path())
|
||||
.tap_err(|_| log::error!("Failed to read stored sphinx key files"))?;
|
||||
Ok(sphinx_keypair)
|
||||
}
|
||||
|
||||
let pathfinder = ClientKeysPathfinder::new_from_config(config);
|
||||
let identity_keypair = load_identity_keys(&pathfinder)?;
|
||||
let sphinx_keypair = load_sphinx_keys(&pathfinder)?;
|
||||
pub fn get_client_address_from_stored_ondisk_keys(
|
||||
pathfinder: &ClientKeysPathfinder,
|
||||
gateway_config: &GatewayEndpointConfig,
|
||||
) -> Result<Recipient, ClientCoreError> {
|
||||
let public_identity: identity::PublicKey =
|
||||
nym_pemstore::load_key(&pathfinder.public_identity_key_file)?;
|
||||
let public_encryption: encryption::PublicKey =
|
||||
nym_pemstore::load_key(&pathfinder.public_encryption_key_file)?;
|
||||
|
||||
let client_recipient = Recipient::new(
|
||||
*identity_keypair.public_key(),
|
||||
*sphinx_keypair.public_key(),
|
||||
public_identity,
|
||||
public_encryption,
|
||||
// TODO: below only works under assumption that gateway address == gateway id
|
||||
// (which currently is true)
|
||||
NodeIdentity::from_base58_string(config.get_gateway_id())?,
|
||||
NodeIdentity::from_base58_string(&gateway_config.gateway_id)?,
|
||||
);
|
||||
|
||||
Ok(client_recipient)
|
||||
|
||||
@@ -128,6 +128,71 @@ pub trait OptionalSet {
|
||||
}
|
||||
}
|
||||
|
||||
// helper for when we want to use `OptionalSet` on an inner field
|
||||
// (used by clients wanting to set the `BaseConfig` values)
|
||||
#[macro_export]
|
||||
macro_rules! define_optional_set_inner {
|
||||
( $x: ident, $inner_field_name: ident, $inner_field_typ: ty ) => {
|
||||
impl $x {
|
||||
pub fn with_optional_inner<F, T>(mut self, f: F, val: Option<T>) -> Self
|
||||
where
|
||||
F: Fn($inner_field_typ, T) -> $inner_field_typ,
|
||||
{
|
||||
self.$inner_field_name = self.$inner_field_name.with_optional(f, val);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_validated_optional_inner<F, T, V, E>(
|
||||
mut self,
|
||||
f: F,
|
||||
value: Option<T>,
|
||||
validate: V,
|
||||
) -> Result<Self, E>
|
||||
where
|
||||
F: Fn($inner_field_typ, T) -> $inner_field_typ,
|
||||
V: Fn(&T) -> Result<(), E>,
|
||||
{
|
||||
self.$inner_field_name = self
|
||||
.$inner_field_name
|
||||
.with_validated_optional(f, value, validate)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_optional_env_inner<F, T>(
|
||||
mut self,
|
||||
f: F,
|
||||
val: Option<T>,
|
||||
env_var: &str,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn($inner_field_typ, T) -> $inner_field_typ,
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: Debug,
|
||||
{
|
||||
self.$inner_field_name = self.$inner_field_name.with_optional_env(f, val, env_var);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_optional_custom_env_inner<F, T, G>(
|
||||
mut self,
|
||||
f: F,
|
||||
val: Option<T>,
|
||||
env_var: &str,
|
||||
parser: G,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn($inner_field_typ, T) -> $inner_field_typ,
|
||||
G: Fn(&str) -> T,
|
||||
{
|
||||
self.$inner_field_name = self
|
||||
.$inner_field_name
|
||||
.with_optional_custom_env(f, val, env_var, parser);
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// this function is only used for parsing values from the network defaults and thus the "expect" there are fine
|
||||
pub fn parse_urls(raw: &str) -> Vec<url::Url> {
|
||||
raw.split(',')
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use crate::ephemeral_storage::EphemeralStorage;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::persistent_storage::PersistentStorage;
|
||||
use std::path::Path;
|
||||
|
||||
mod backends;
|
||||
pub mod ephemeral_storage;
|
||||
@@ -16,7 +17,7 @@ pub mod persistent_storage;
|
||||
pub mod storage;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub async fn initialise_persistent_storage(path: std::path::PathBuf) -> PersistentStorage {
|
||||
pub async fn initialise_persistent_storage<P: AsRef<Path>>(path: P) -> PersistentStorage {
|
||||
match persistent_storage::PersistentStorage::init(path).await {
|
||||
Err(err) => panic!("failed to initialise credential storage - {err}"),
|
||||
Ok(storage) => storage,
|
||||
|
||||
@@ -23,7 +23,7 @@ impl PersistentStorage {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `database_path`: path to the database.
|
||||
pub async fn init<P: AsRef<Path> + Send>(database_path: P) -> Result<Self, StorageError> {
|
||||
pub async fn init<P: AsRef<Path>>(database_path: P) -> Result<Self, StorageError> {
|
||||
debug!(
|
||||
"Attempting to connect to database {:?}",
|
||||
database_path.as_ref().as_os_str()
|
||||
|
||||
@@ -98,7 +98,7 @@ fn print_signed_text(
|
||||
|
||||
let signature = private_key.sign_text(text);
|
||||
let sign_output = ConsoleSigningOutput::new(text, signature);
|
||||
println!("{}", output.format(&sign_output));
|
||||
println!("{}", output.format(&sign_outpuant));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -96,11 +96,14 @@ pub(crate) fn execute(args: &Init) {
|
||||
eprintln!("Saved mixnet identity and sphinx keypairs");
|
||||
}
|
||||
|
||||
let config_save_location = default_config_filepath(id);
|
||||
let config_save_location = config.default_location();
|
||||
config
|
||||
.save_to_default_location()
|
||||
.expect("Failed to save the config file");
|
||||
eprintln!("Saved configuration file to {config_save_location:?}");
|
||||
eprintln!(
|
||||
"Saved configuration file to {}",
|
||||
config_save_location.display()
|
||||
);
|
||||
eprintln!("Mixnode configuration completed.\n\n\n");
|
||||
|
||||
MixNode::new(config).print_node_details(args.output)
|
||||
|
||||
@@ -105,8 +105,12 @@ impl Config {
|
||||
Self::read_from_toml_file(default_config_filepath(id))
|
||||
}
|
||||
|
||||
pub fn default_location(&self) -> PathBuf {
|
||||
default_config_filepath(&self.mixnode.id)
|
||||
}
|
||||
|
||||
pub fn save_to_default_location(&self) -> io::Result<()> {
|
||||
let config_save_location: PathBuf = default_config_filepath(&self.mixnode.id);
|
||||
let config_save_location: PathBuf = self.default_location();
|
||||
save_formatted_config_to_file(self, config_save_location)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user