Feature/nymd client integration (#736)
* Calculating gas fees * Ability to set custom fees * Added extra test * Removed commented code * Moved all msg types to common contract crate * Temporarily disabling get_tx method * Finishing up nymd client API * Comment fix * Remaining fee values * Some cleanup * Removed needless borrow * Fixed imports in contract tests * Moved error types around * New ValidatorClient * Experiment with new type of defaults * Removed dead module * Dealt with unwrap * Migrated mixnode to use new validator client * Migrated gateway to use new validator client * Mixnode and gateway adjustments * More exported defaults * Clients using new validator client * Fixed mixnode upgrade * Moved default values to a new crate * Changed behaviour of validator client features * Migrated basic functions of validator api * Updated config + fixed startup * Fixed wasm client build * Integration with the explorer api * Removed tokio dev dependency * Needless borrow * Fixex wasm client build * Fixed tauri client build * Needless borrows * Fixed client upgrade print * Removed redundant comments * Made note on aggregated verification key into a doc comment * Removed mixnet contract references from verloc * Modified default validators structure * Reformatted validator-api Cargo.toml file * Removed commented code * Made the doc comment example a no-run * Fixed a upgrade print... again * Adjusted the doc example * Removed unused import
This commit is contained in:
committed by
GitHub
parent
eec211e038
commit
a274edffba
@@ -56,12 +56,6 @@ pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
|
||||
.help("Comma separated list of rest endpoints of the validators")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(CONTRACT_ARG_NAME)
|
||||
.long(CONTRACT_ARG_NAME)
|
||||
.help("Address of the validator contract managing the network")
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn show_bonding_info(config: &Config) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::config::Config;
|
||||
use clap::ArgMatches;
|
||||
use url::Url;
|
||||
|
||||
pub(crate) mod describe;
|
||||
pub(crate) mod init;
|
||||
@@ -16,12 +17,16 @@ pub(crate) const MIX_PORT_ARG_NAME: &str = "mix-port";
|
||||
pub(crate) const VERLOC_PORT_ARG_NAME: &str = "verloc-port";
|
||||
pub(crate) const HTTP_API_PORT_ARG_NAME: &str = "http-api-port";
|
||||
pub(crate) const VALIDATORS_ARG_NAME: &str = "validators";
|
||||
pub(crate) const CONTRACT_ARG_NAME: &str = "mixnet-contract";
|
||||
pub(crate) const ANNOUNCE_HOST_ARG_NAME: &str = "announce-host";
|
||||
|
||||
fn parse_validators(raw: &str) -> Vec<String> {
|
||||
fn parse_validators(raw: &str) -> Vec<Url> {
|
||||
raw.split(',')
|
||||
.map(|raw_validator| raw_validator.trim().into())
|
||||
.map(|raw_validator| {
|
||||
raw_validator
|
||||
.trim()
|
||||
.parse()
|
||||
.expect("one of the provided validator api urls is invalid")
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -66,11 +71,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Confi
|
||||
}
|
||||
|
||||
if let Some(raw_validators) = matches.value_of(VALIDATORS_ARG_NAME) {
|
||||
config = config.with_custom_validators(parse_validators(raw_validators));
|
||||
}
|
||||
|
||||
if let Some(contract_address) = matches.value_of(CONTRACT_ARG_NAME) {
|
||||
config = config.with_custom_mixnet_contract(contract_address)
|
||||
config = config.with_custom_validator_apis(parse_validators(raw_validators));
|
||||
}
|
||||
|
||||
if let Some(announce_host) = matches.value_of(ANNOUNCE_HOST_ARG_NAME) {
|
||||
|
||||
@@ -58,12 +58,6 @@ pub fn command_args<'a, 'b>() -> App<'a, 'b> {
|
||||
.help("Comma separated list of rest endpoints of the validators")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(CONTRACT_ARG_NAME)
|
||||
.long(CONTRACT_ARG_NAME)
|
||||
.help("Address of the validator contract managing the network")
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn show_binding_warning(address: String) {
|
||||
@@ -151,7 +145,7 @@ pub fn execute(matches: &ArgMatches) {
|
||||
|
||||
println!(
|
||||
"Validator servers: {:?}",
|
||||
config.get_validator_rest_endpoints()
|
||||
config.get_validator_api_endpoints()
|
||||
);
|
||||
println!(
|
||||
"Listening for incoming packets on {}",
|
||||
|
||||
+47
-363
@@ -2,25 +2,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::commands::*;
|
||||
use crate::config::{
|
||||
default_validator_rest_endpoints, missing_string_value, Config, MISSING_VALUE,
|
||||
};
|
||||
use crate::node::node_description::{NodeDescription, DESCRIPTION_FILE};
|
||||
use crate::config::{missing_string_value, Config};
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use config::defaults::DEFAULT_MIXNET_CONTRACT_ADDRESS;
|
||||
use config::defaults::default_api_endpoints;
|
||||
use config::NymConfig;
|
||||
use crypto::asymmetric::identity;
|
||||
use serde::Deserialize;
|
||||
use std::fmt::Display;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::{fs, process};
|
||||
use version_checker::{parse_version, Version};
|
||||
|
||||
type UpgradeError = (Version, String);
|
||||
const CURRENT_VERSION_ARG_NAME: &str = "current-version";
|
||||
use std::process;
|
||||
use version_checker::Version;
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn fail_upgrade<D1: Display, D2: Display>(from_version: D1, to_version: D2) -> ! {
|
||||
print_failed_upgrade(from_version, to_version);
|
||||
process::exit(1)
|
||||
@@ -47,28 +37,29 @@ fn print_successful_upgrade<D1: Display, D2: Display>(from: D1, to: D2) {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn command_args<'a, 'b>() -> App<'a, 'b> {
|
||||
App::new("upgrade").about("Try to upgrade the mixnode")
|
||||
.arg(
|
||||
Arg::with_name(ID_ARG_NAME)
|
||||
.long(ID_ARG_NAME)
|
||||
.help("Id of the nym-mixnode we want to upgrade")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
// the rest of arguments depend on the upgrade path
|
||||
.arg(Arg::with_name(CURRENT_VERSION_ARG_NAME)
|
||||
.long(CURRENT_VERSION_ARG_NAME)
|
||||
.help("REQUIRED FOR PRE-0.9.0 UPGRADES. Specifies current version of the configuration file to help to determine a valid upgrade path. Valid formats include '0.8.1', 'v0.8.1' or 'V0.8.1'")
|
||||
.takes_value(true)
|
||||
)
|
||||
fn outdated_upgrade(config_version: &Version, package_version: &Version) -> ! {
|
||||
eprintln!(
|
||||
"Cannot perform upgrade from {} to {}. Your version is too old to perform the upgrade.!",
|
||||
config_version, package_version
|
||||
);
|
||||
process::exit(1)
|
||||
}
|
||||
|
||||
fn unsupported_upgrade(config_version: Version, package_version: Version) -> ! {
|
||||
fn unsupported_upgrade(config_version: &Version, package_version: &Version) -> ! {
|
||||
eprintln!("Cannot perform upgrade from {} to {}. Please let the developers know about this issue if you expected it to work!", config_version, package_version);
|
||||
process::exit(1)
|
||||
}
|
||||
|
||||
pub fn command_args<'a, 'b>() -> App<'a, 'b> {
|
||||
App::new("upgrade").about("Try to upgrade the mixnode").arg(
|
||||
Arg::with_name(ID_ARG_NAME)
|
||||
.long(ID_ARG_NAME)
|
||||
.help("Id of the nym-mixnode we want to upgrade")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_config_version(config: &Config) -> Version {
|
||||
let version = Version::parse(config.get_version()).unwrap_or_else(|err| {
|
||||
eprintln!("failed to parse client version! - {:?}", err);
|
||||
@@ -103,276 +94,40 @@ fn parse_package_version() -> Version {
|
||||
version
|
||||
}
|
||||
|
||||
fn pre_090_upgrade(from: &str, config: Config) -> Config {
|
||||
// note: current is guaranteed to not have any `build` information suffix (nor pre-release
|
||||
// information), as this was asserted at the beginning of this command)
|
||||
//
|
||||
// upgrade to current (if it's a 0.9.X) or try to upgrade to 0.9.0 as an intermediate
|
||||
// step in future upgrades (so, for example, we might go 0.8.0 -> 0.9.0 -> 0.10.0)
|
||||
// this way we don't need to have all the crazy paths on how to upgrade from any version to any
|
||||
// other version. We just upgrade one minor version at a time.
|
||||
let current = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
||||
let to_version = if current.major == 0 && current.minor == 9 {
|
||||
current
|
||||
fn minor_0_12_upgrade(
|
||||
config: Config,
|
||||
_matches: &ArgMatches,
|
||||
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, 9, 0)
|
||||
Version::new(0, 12, 0)
|
||||
};
|
||||
|
||||
print_start_upgrade(&from, &to_version);
|
||||
|
||||
// this is not extracted to separate function as you only have to manually pass version
|
||||
// if upgrading from pre090 version
|
||||
let from = match from.strip_prefix('v') {
|
||||
Some(stripped) => stripped,
|
||||
None => from,
|
||||
};
|
||||
|
||||
let from = match from.strip_prefix('V') {
|
||||
Some(stripped) => stripped,
|
||||
None => from,
|
||||
};
|
||||
|
||||
let from_version = parse_version(from).expect("invalid version provided!");
|
||||
if from_version.major == 0 && from_version.minor < 8 {
|
||||
// technically this could be implemented, but is there any point in that?
|
||||
eprintln!("upgrading node from before v0.8.0 is not supported. Please run `init` with new binary instead");
|
||||
fail_upgrade(&from_version, &to_version)
|
||||
}
|
||||
|
||||
if (from_version.major == 0 && from_version.minor >= 9) || from_version.major >= 1 {
|
||||
eprintln!("self reported version is higher than 0.9.0. Those releases should have already contained version numbers in config! Make sure you provided correct version");
|
||||
fail_upgrade(&from_version, &to_version)
|
||||
}
|
||||
|
||||
if config.get_private_identity_key_file() != missing_string_value::<PathBuf>()
|
||||
|| config.get_public_identity_key_file() != missing_string_value::<PathBuf>()
|
||||
{
|
||||
eprintln!("existing config seems to have specified identity keys which were only introduced in 0.9.0! Can't perform upgrade.");
|
||||
fail_upgrade(&from_version, &to_version)
|
||||
}
|
||||
|
||||
if config.get_validator_rest_endpoints()[0] != missing_string_value::<String>() {
|
||||
eprintln!("existing config seems to have specified new validator rest endpoint which was only introduced in 0.9.0! Can't perform upgrade.");
|
||||
fail_upgrade(&from_version, &to_version)
|
||||
}
|
||||
|
||||
let mut upgraded_config = config
|
||||
.with_custom_version(to_version.to_string().as_ref())
|
||||
.with_custom_validators(default_validator_rest_endpoints());
|
||||
print_start_upgrade(&config_version, &to_version);
|
||||
|
||||
println!(
|
||||
"Setting validator REST endpoints to {:?}",
|
||||
default_validator_rest_endpoints()
|
||||
"Setting validator API endpoints to {:?}",
|
||||
default_api_endpoints()
|
||||
);
|
||||
|
||||
println!("Generating new identity...");
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let identity_keys = identity::KeyPair::new(&mut rng);
|
||||
upgraded_config.set_default_identity_keypair_paths();
|
||||
|
||||
if let Err(err) = pemstore::store_keypair(
|
||||
&identity_keys,
|
||||
&pemstore::KeyPairPath::new(
|
||||
upgraded_config.get_private_identity_key_file(),
|
||||
upgraded_config.get_public_identity_key_file(),
|
||||
),
|
||||
) {
|
||||
eprintln!("Failed to save new identity key files! - {}", err);
|
||||
process::exit(1);
|
||||
}
|
||||
let upgraded_config = config
|
||||
.with_custom_version(to_version.to_string().as_ref())
|
||||
.with_custom_validator_apis(default_api_endpoints());
|
||||
|
||||
upgraded_config.save_to_file(None).unwrap_or_else(|err| {
|
||||
eprintln!("failed to overwrite config file! - {:?}", err);
|
||||
fail_upgrade(&from_version, &to_version)
|
||||
print_failed_upgrade(&config_version, &to_version);
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
print_successful_upgrade(from_version, to_version);
|
||||
print_successful_upgrade(config_version, to_version);
|
||||
|
||||
upgraded_config
|
||||
}
|
||||
|
||||
fn minor_0_10_upgrade(
|
||||
config: Config,
|
||||
_matches: &ArgMatches,
|
||||
config_version: &Version,
|
||||
package_version: &Version,
|
||||
) -> Result<Config, UpgradeError> {
|
||||
let to_version = if package_version.major == 0 && package_version.minor == 10 {
|
||||
package_version.clone()
|
||||
} else {
|
||||
Version::new(0, 10, 0)
|
||||
};
|
||||
|
||||
print_start_upgrade(&config_version, &to_version);
|
||||
|
||||
if config.get_validator_mixnet_contract_address() != MISSING_VALUE {
|
||||
return Err((to_version, "existing config seems to have specified mixnet contract address which was only introduced in 0.10.0! Can't perform upgrade.".to_string()));
|
||||
}
|
||||
|
||||
println!(
|
||||
"Setting validator REST endpoint to {:?}",
|
||||
default_validator_rest_endpoints()
|
||||
);
|
||||
|
||||
println!(
|
||||
"Setting mixnet contract address to {}",
|
||||
DEFAULT_MIXNET_CONTRACT_ADDRESS
|
||||
);
|
||||
|
||||
let upgraded_config = config
|
||||
.with_custom_version(to_version.to_string().as_ref())
|
||||
.with_custom_validators(default_validator_rest_endpoints())
|
||||
.with_custom_mixnet_contract(DEFAULT_MIXNET_CONTRACT_ADDRESS);
|
||||
|
||||
upgraded_config.save_to_file(None).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to overwrite config file! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
print_successful_upgrade(config_version, to_version);
|
||||
|
||||
Ok(upgraded_config)
|
||||
}
|
||||
|
||||
fn patch_0_10_1_upgrade(
|
||||
config: Config,
|
||||
_matches: &ArgMatches,
|
||||
config_version: &Version,
|
||||
package_version: &Version,
|
||||
) -> Result<Config, UpgradeError> {
|
||||
// welp, stuff like ports are mostly hardcoded and not part of the config so all is changes is just the version
|
||||
// number
|
||||
let to_version = package_version;
|
||||
|
||||
print_start_upgrade(&config_version, &to_version);
|
||||
|
||||
let upgraded_config = config.with_custom_version(to_version.to_string().as_ref());
|
||||
|
||||
upgraded_config.save_to_file(None).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to overwrite config file! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
print_successful_upgrade(config_version, to_version);
|
||||
|
||||
Ok(upgraded_config)
|
||||
}
|
||||
|
||||
fn minor_0_11_upgrade(
|
||||
config: Config,
|
||||
_matches: &ArgMatches,
|
||||
config_version: &Version,
|
||||
package_version: &Version,
|
||||
) -> Result<Config, UpgradeError> {
|
||||
let to_version = if package_version.major == 0 && package_version.minor == 11 {
|
||||
package_version.clone()
|
||||
} else {
|
||||
Version::new(0, 11, 0)
|
||||
};
|
||||
|
||||
let id = config.get_id();
|
||||
let config_path = Config::default_config_directory(Some(&id));
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct OldNodeDescription {
|
||||
name: String,
|
||||
description: String,
|
||||
link: String,
|
||||
}
|
||||
|
||||
print_start_upgrade(&config_version, &to_version);
|
||||
|
||||
// description action
|
||||
let description_file_path: PathBuf = [config_path.to_str().unwrap(), DESCRIPTION_FILE]
|
||||
.iter()
|
||||
.collect();
|
||||
// If the description file already exists, upgrade it
|
||||
let new_description = if description_file_path.is_file() {
|
||||
let description_content = fs::read_to_string(description_file_path).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to read description file! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
let old_description: OldNodeDescription =
|
||||
toml::from_str(&description_content).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to deserialize description content! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
Some(NodeDescription {
|
||||
name: old_description.name,
|
||||
description: old_description.description,
|
||||
link: old_description.link,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let current_annnounce_addr = config.get_announce_address();
|
||||
// try to parse it as socket address directly
|
||||
let (announce_address, custom_mix_port) = match SocketAddr::from_str(¤t_annnounce_addr) {
|
||||
Ok(addr) => (addr.ip().to_string(), addr.port()),
|
||||
Err(_) => {
|
||||
let announce_split = current_annnounce_addr.split(':').collect::<Vec<_>>();
|
||||
if announce_split.len() != 2 {
|
||||
return Err((
|
||||
to_version,
|
||||
"failed to correctly parse current announce host".to_string(),
|
||||
));
|
||||
}
|
||||
(
|
||||
announce_split[0].to_string(),
|
||||
announce_split[1].parse().unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
println!(
|
||||
"Setting validator REST endpoint to {:?}",
|
||||
default_validator_rest_endpoints()
|
||||
);
|
||||
|
||||
println!(
|
||||
"Setting mixnet contract address to {}",
|
||||
DEFAULT_MIXNET_CONTRACT_ADDRESS
|
||||
);
|
||||
|
||||
let upgraded_config = config
|
||||
.with_custom_version(to_version.to_string().as_ref())
|
||||
.with_announce_address(announce_address)
|
||||
.with_mix_port(custom_mix_port)
|
||||
.with_custom_validators(default_validator_rest_endpoints())
|
||||
.with_custom_mixnet_contract(DEFAULT_MIXNET_CONTRACT_ADDRESS);
|
||||
|
||||
if let Some(new_description) = new_description {
|
||||
NodeDescription::save_to_file(&new_description, config_path).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to overwrite description file! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
upgraded_config.save_to_file(None).map_err(|err| {
|
||||
(
|
||||
to_version.clone(),
|
||||
format!("failed to overwrite config file! - {:?}", err),
|
||||
)
|
||||
})?;
|
||||
|
||||
print_successful_upgrade(config_version, to_version);
|
||||
|
||||
Ok(upgraded_config)
|
||||
}
|
||||
|
||||
fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version) {
|
||||
loop {
|
||||
let config_version = parse_config_version(&config);
|
||||
@@ -384,30 +139,12 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version
|
||||
|
||||
config = match config_version.major {
|
||||
0 => match config_version.minor {
|
||||
9 => minor_0_10_upgrade(config, matches, &config_version, &Version::new(0, 10, 0)),
|
||||
10 => match config_version.patch {
|
||||
0 => patch_0_10_1_upgrade(
|
||||
config,
|
||||
matches,
|
||||
&config_version,
|
||||
&Version::new(0, 10, 1),
|
||||
),
|
||||
_ => minor_0_11_upgrade(
|
||||
config,
|
||||
matches,
|
||||
&config_version,
|
||||
&Version::new(0, 11, 0),
|
||||
),
|
||||
},
|
||||
_ => unsupported_upgrade(config_version, package_version),
|
||||
9 | 10 => outdated_upgrade(&config_version, &package_version),
|
||||
11 => minor_0_12_upgrade(config, matches, &config_version, &package_version),
|
||||
_ => unsupported_upgrade(&config_version, &package_version),
|
||||
},
|
||||
_ => unsupported_upgrade(config_version, package_version),
|
||||
_ => unsupported_upgrade(&config_version, &package_version),
|
||||
}
|
||||
.unwrap_or_else(|(to_version, err)| {
|
||||
eprintln!("{:?}", err);
|
||||
print_failed_upgrade(&config_version, &to_version);
|
||||
process::exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,68 +153,15 @@ pub fn execute(matches: &ArgMatches) {
|
||||
|
||||
let id = matches.value_of(ID_ARG_NAME).unwrap();
|
||||
|
||||
let mut existing_config = Config::load_from_file(Some(id)).unwrap_or_else(|err| {
|
||||
let existing_config = Config::load_from_file(Some(id)).unwrap_or_else(|err| {
|
||||
eprintln!("failed to load existing config file! - {:?}", err);
|
||||
process::exit(1)
|
||||
});
|
||||
|
||||
// versions fields were added in 0.9.0
|
||||
if existing_config.get_version() == missing_string_value::<String>() {
|
||||
let self_reported_version =
|
||||
matches
|
||||
.value_of(CURRENT_VERSION_ARG_NAME)
|
||||
.unwrap_or_else(|| {
|
||||
eprintln!(
|
||||
"trying to upgrade from pre v0.9.0 without providing current system version!"
|
||||
);
|
||||
process::exit(1)
|
||||
});
|
||||
|
||||
// upgrades up to 0.9.0
|
||||
existing_config = pre_090_upgrade(self_reported_version, existing_config);
|
||||
eprintln!("the existing configuration file does not seem to contain version number.");
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
// here be upgrade path to 0.9.X and beyond based on version number from config
|
||||
do_upgrade(existing_config, matches, package_version)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod upgrade_tests {
|
||||
use super::*;
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_0_10_2_upgrade() {
|
||||
let config = Config::default()
|
||||
.with_id("-42")
|
||||
.with_announce_address("127.0.0.1:1234")
|
||||
.with_custom_version("0.10.1");
|
||||
let matches = ArgMatches::default();
|
||||
let old_version = Version::new(0, 10, 1);
|
||||
let new_version = Version::new(0, 10, 2);
|
||||
let new_config = minor_0_11_upgrade(config, &matches, &old_version, &new_version).unwrap();
|
||||
assert_eq!(new_config.get_version(), "0.11.0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_0_10_2_upgrade_error() {
|
||||
let config = Config::default()
|
||||
.with_id("-42")
|
||||
.with_announce_address("127.0.0.1:1234")
|
||||
.with_custom_version("0.10.1");
|
||||
let matches = ArgMatches::default();
|
||||
let old_version = Version::new(0, 10, 1);
|
||||
let new_version = Version::new(0, 10, 2);
|
||||
config.save_to_file(None).unwrap();
|
||||
let config_file = config.get_config_file_save_location();
|
||||
let initial_perms = fs::metadata(config_file.clone()).unwrap().permissions();
|
||||
let mut new_perms = initial_perms.clone();
|
||||
new_perms.set_readonly(true);
|
||||
fs::set_permissions(config_file.clone(), new_perms).unwrap();
|
||||
let ret = minor_0_11_upgrade(config, &matches, &old_version, &new_version);
|
||||
fs::set_permissions(config_file, initial_perms).unwrap();
|
||||
assert!(ret.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
+18
-71
@@ -3,12 +3,13 @@
|
||||
|
||||
use crate::config::template::config_template;
|
||||
use config::defaults::*;
|
||||
use config::{deserialize_duration, deserialize_validators, NymConfig};
|
||||
use config::NymConfig;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
pub mod persistence;
|
||||
mod template;
|
||||
@@ -32,22 +33,10 @@ const DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF: Duration = Duration::from_milli
|
||||
const DEFAULT_INITIAL_CONNECTION_TIMEOUT: Duration = Duration::from_millis(1_500);
|
||||
const DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE: usize = 128;
|
||||
|
||||
// helper function to get default validators as a Vec<String>
|
||||
pub fn default_validator_rest_endpoints() -> Vec<String> {
|
||||
DEFAULT_VALIDATOR_REST_ENDPOINTS
|
||||
.iter()
|
||||
.map(|&endpoint| endpoint.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn missing_string_value<T: From<String>>() -> T {
|
||||
MISSING_VALUE.to_string().into()
|
||||
}
|
||||
|
||||
pub fn missing_vec_string_value() -> Vec<String> {
|
||||
vec![missing_string_value()]
|
||||
}
|
||||
|
||||
fn bind_all_address() -> IpAddr {
|
||||
"0.0.0.0".parse().unwrap()
|
||||
}
|
||||
@@ -159,13 +148,8 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_custom_validators(mut self, validators: Vec<String>) -> Self {
|
||||
self.mixnode.validator_rest_urls = validators;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_custom_mixnet_contract<S: Into<String>>(mut self, mixnet_contract: S) -> Self {
|
||||
self.mixnode.mixnet_contract_address = mixnet_contract.into();
|
||||
pub fn with_custom_validator_apis(mut self, validator_api_urls: Vec<Url>) -> Self {
|
||||
self.mixnode.validator_api_urls = validator_api_urls;
|
||||
self
|
||||
}
|
||||
|
||||
@@ -233,12 +217,8 @@ impl Config {
|
||||
self.mixnode.public_sphinx_key_file.clone()
|
||||
}
|
||||
|
||||
pub fn get_validator_rest_endpoints(&self) -> Vec<String> {
|
||||
self.mixnode.validator_rest_urls.clone()
|
||||
}
|
||||
|
||||
pub fn get_validator_mixnet_contract_address(&self) -> String {
|
||||
self.mixnode.mixnet_contract_address.clone()
|
||||
pub fn get_validator_api_endpoints(&self) -> Vec<Url> {
|
||||
self.mixnode.validator_api_urls.clone()
|
||||
}
|
||||
|
||||
pub fn get_node_stats_logging_delay(&self) -> Duration {
|
||||
@@ -289,13 +269,10 @@ impl Config {
|
||||
&self.mixnode.version
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> String {
|
||||
self.mixnode.id.clone()
|
||||
}
|
||||
|
||||
pub fn get_measurement_packets_per_node(&self) -> usize {
|
||||
self.verloc.packets_per_node
|
||||
}
|
||||
|
||||
pub fn get_measurement_packet_timeout(&self) -> Duration {
|
||||
self.verloc.packet_timeout
|
||||
}
|
||||
@@ -307,23 +284,18 @@ impl Config {
|
||||
pub fn get_measurement_delay_between_packets(&self) -> Duration {
|
||||
self.verloc.delay_between_packets
|
||||
}
|
||||
|
||||
pub fn get_measurement_tested_nodes_batch_size(&self) -> usize {
|
||||
self.verloc.tested_nodes_batch_size
|
||||
}
|
||||
|
||||
pub fn get_measurement_testing_interval(&self) -> Duration {
|
||||
self.verloc.testing_interval
|
||||
}
|
||||
|
||||
pub fn get_measurement_retry_timeout(&self) -> Duration {
|
||||
self.verloc.retry_timeout
|
||||
}
|
||||
|
||||
// upgrade-specific
|
||||
pub(crate) fn set_default_identity_keypair_paths(&mut self) {
|
||||
self.mixnode.private_identity_key_file =
|
||||
self::MixNode::default_private_identity_key_file(&self.mixnode.id);
|
||||
self.mixnode.public_identity_key_file =
|
||||
self::MixNode::default_public_identity_key_file(&self.mixnode.id);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
@@ -373,17 +345,8 @@ pub struct MixNode {
|
||||
/// Path to file containing public sphinx key.
|
||||
public_sphinx_key_file: PathBuf,
|
||||
|
||||
/// Validator server from which the node gets the view on the network.
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_validators",
|
||||
default = "missing_vec_string_value",
|
||||
alias = "validator_rest_url"
|
||||
)]
|
||||
validator_rest_urls: Vec<String>,
|
||||
|
||||
/// Address of the validator contract managing the network.
|
||||
#[serde(default = "missing_string_value")]
|
||||
mixnet_contract_address: String,
|
||||
/// Addresses to APIs running on validator from which the node gets the view of the network.
|
||||
validator_api_urls: Vec<Url>,
|
||||
|
||||
/// nym_home_directory specifies absolute path to the home nym MixNodes directory.
|
||||
/// It is expected to use default value and hence .toml file should not redefine this field.
|
||||
@@ -422,8 +385,7 @@ impl Default for MixNode {
|
||||
public_identity_key_file: Default::default(),
|
||||
private_sphinx_key_file: Default::default(),
|
||||
public_sphinx_key_file: Default::default(),
|
||||
validator_rest_urls: default_validator_rest_endpoints(),
|
||||
mixnet_contract_address: DEFAULT_MIXNET_CONTRACT_ADDRESS.to_string(),
|
||||
validator_api_urls: default_api_endpoints(),
|
||||
nym_root_directory: Config::default_root_directory(),
|
||||
}
|
||||
}
|
||||
@@ -483,40 +445,25 @@ impl Default for Verloc {
|
||||
#[serde(default)]
|
||||
pub struct Debug {
|
||||
/// Delay between each subsequent node statistics being logged to the console
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_duration",
|
||||
serialize_with = "humantime_serde::serialize"
|
||||
)]
|
||||
#[serde(with = "humantime_serde")]
|
||||
node_stats_logging_delay: Duration,
|
||||
|
||||
/// Delay between each subsequent node statistics being updated
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_duration",
|
||||
serialize_with = "humantime_serde::serialize"
|
||||
)]
|
||||
#[serde(with = "humantime_serde")]
|
||||
node_stats_updating_delay: Duration,
|
||||
|
||||
/// Initial value of an exponential backoff to reconnect to dropped TCP connection when
|
||||
/// forwarding sphinx packets.
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_duration",
|
||||
serialize_with = "humantime_serde::serialize"
|
||||
)]
|
||||
#[serde(with = "humantime_serde")]
|
||||
packet_forwarding_initial_backoff: Duration,
|
||||
|
||||
/// Maximum value of an exponential backoff to reconnect to dropped TCP connection when
|
||||
/// forwarding sphinx packets.
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_duration",
|
||||
serialize_with = "humantime_serde::serialize"
|
||||
)]
|
||||
#[serde(with = "humantime_serde")]
|
||||
packet_forwarding_maximum_backoff: Duration,
|
||||
|
||||
/// Timeout for establishing initial connection when trying to forward a sphinx packet.
|
||||
#[serde(
|
||||
deserialize_with = "deserialize_duration",
|
||||
serialize_with = "humantime_serde::serialize"
|
||||
)]
|
||||
#[serde(with = "humantime_serde")]
|
||||
initial_connection_timeout: Duration,
|
||||
|
||||
/// Maximum number of packets that can be stored waiting to get sent to a particular connection.
|
||||
|
||||
@@ -53,16 +53,13 @@ verloc_port = {{ mixnode.verloc_port }}
|
||||
# (default: 8000)
|
||||
http_api_port = {{ mixnode.http_api_port }}
|
||||
|
||||
# Validator server to which the node will be getting information about the network.
|
||||
validator_rest_urls = [
|
||||
{{#each mixnode.validator_rest_urls }}
|
||||
# Addresses to APIs running on validator from which the node gets the view of the network.
|
||||
validator_api_urls = [
|
||||
{{#each mixnode.validator_api_urls }}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
]
|
||||
|
||||
# Address of the validator contract managing the network.
|
||||
mixnet_contract_address = '{{ mixnode.mixnet_contract_address }}'
|
||||
|
||||
##### advanced configuration options #####
|
||||
|
||||
# Absolute path to the home Nym Clients directory.
|
||||
|
||||
@@ -17,6 +17,8 @@ use crate::node::packet_delayforwarder::{DelayForwarder, PacketDelayForwardSende
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
use log::{error, info, warn};
|
||||
use mixnode_common::verloc::{self, AtomicVerlocResult, VerlocMeasurer};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use std::net::SocketAddr;
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
@@ -164,8 +166,7 @@ impl MixNode {
|
||||
.tested_nodes_batch_size(self.config.get_measurement_tested_nodes_batch_size())
|
||||
.testing_interval(self.config.get_measurement_testing_interval())
|
||||
.retry_timeout(self.config.get_measurement_retry_timeout())
|
||||
.validator_urls(self.config.get_validator_rest_endpoints())
|
||||
.mixnet_contract_address(self.config.get_validator_mixnet_contract_address())
|
||||
.validator_api_urls(self.config.get_validator_api_endpoints())
|
||||
.build();
|
||||
|
||||
let mut verloc_measurer = VerlocMeasurer::new(config, Arc::clone(&self.identity_keypair));
|
||||
@@ -176,13 +177,13 @@ impl MixNode {
|
||||
|
||||
// TODO: ask DH whether this function still makes sense in ^0.10
|
||||
async fn check_if_same_ip_node_exists(&mut self) -> Option<String> {
|
||||
let validator_client_config = validator_client::Config::new(
|
||||
self.config.get_validator_rest_endpoints(),
|
||||
self.config.get_validator_mixnet_contract_address(),
|
||||
);
|
||||
let validator_client = validator_client::Client::new(validator_client_config);
|
||||
let endpoints = self.config.get_validator_api_endpoints();
|
||||
let validator_api = endpoints
|
||||
.choose(&mut thread_rng())
|
||||
.expect("The list of validator apis is empty");
|
||||
let validator_client = validator_client::ApiClient::new(validator_api.clone());
|
||||
|
||||
let existing_nodes = match validator_client.get_cached_mix_nodes().await {
|
||||
let existing_nodes = match validator_client.get_cached_mixnodes().await {
|
||||
Ok(nodes) => nodes,
|
||||
Err(err) => {
|
||||
error!("failed to grab initial network mixnodes - {}\n Please try to startup again in few minutes", err);
|
||||
|
||||
Reference in New Issue
Block a user