diff --git a/gateway/src/commands/upgrade.rs b/gateway/src/commands/upgrade.rs index ee9fa4fb1b..31d79a2cd1 100644 --- a/gateway/src/commands/upgrade.rs +++ b/gateway/src/commands/upgrade.rs @@ -1,14 +1,22 @@ // Copyright 2020 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::config::DEFAULT_MIXNET_CONTRACT_ADDRESS; -use crate::config::{default_validator_rest_endpoints, Config, MISSING_VALUE}; -use clap::{App, Arg, ArgMatches}; -use config::NymConfig; use std::fmt::Display; use std::process; + +use clap::{App, Arg, ArgMatches}; + +use config::NymConfig; use version_checker::{parse_version, Version}; +use crate::config::DEFAULT_MIXNET_CONTRACT_ADDRESS; +use crate::config::{default_validator_rest_endpoints, Config, MISSING_VALUE}; + +fn fail_upgrade(from_version: D1, to_version: D2) -> ! { + print_failed_upgrade(from_version, to_version); + process::exit(1) +} + fn print_start_upgrade(from: D1, to: D2) { println!( "\n==================\nTrying to upgrade gateway from {} to {} ...", @@ -45,6 +53,16 @@ pub fn command_args<'a, 'b>() -> App<'a, 'b> { .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) ) + .arg(Arg::with_name("listening-address") + .long("listening-address") + .help("REQUIRED FOR 0.Y.Z UPGRADE. Specifies the listening address of this gateway") + .takes_value(true) + ) + .arg(Arg::with_name("announce-address") + .long("announce-address") + .help("OPTIONAL FOR 0.Y.Z UPGRADE. Specifies the announce address of this gateway. If not provided, it will be set to the same value as listening address") + .takes_value(true) + ) } fn unsupported_upgrade(current_version: Version, config_version: Version) -> ! { @@ -169,8 +187,7 @@ fn minor_010_upgrade( if config.get_validator_mixnet_contract_address() != MISSING_VALUE { eprintln!("existing config seems to have specified mixnet contract address which was only introduced in 0.10.0! Can't perform upgrade."); - print_failed_upgrade(&config_version, &to_version); - process::exit(1); + fail_upgrade(&config_version, &to_version) } println!( @@ -190,8 +207,7 @@ fn minor_010_upgrade( upgraded_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); + fail_upgrade(&config_version, &to_version) }); print_successful_upgrade(config_version, to_version); @@ -214,8 +230,58 @@ fn patch_010_upgrade( upgraded_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); + fail_upgrade(&config_version, &to_version) + }); + + print_successful_upgrade(config_version, to_version); + + upgraded_config +} + +// TODO: to be renamed once the release version is decided (so presumably either 0.10.2 or 0.11.0) +fn undetermined_version_upgrade( + config: Config, + matches: &ArgMatches, + config_version: &Version, + package_version: &Version, +) -> Config { + // If we decide this version should be tagged with 0.11.0, then the following code will be used instead: + // let to_version = if package_version.major == 0 && package_version.minor == 11 { + // package_version.clone() + // } else { + // Version::new(0, 11, 0) + // }; + let to_version = package_version; + + print_start_upgrade(&config_version, &to_version); + + // normally the proper approach would have been to keep old structs, parse file according to old structs + // and move it to the new ones + // however, considering that at this point of time we don't have many gateways and all + // are run by us, this would be an unnecessary code complication and so just providing + // addresses again during upgrade is I think a better approach. + let listening_address = matches.value_of("listening-address").unwrap_or_else(|| { + eprintln!( + "trying to upgrade to {} without providing proper listening address!", + to_version + ); + fail_upgrade(&config_version, &to_version) + }); + + let announce_address = if let Some(announce_addr) = matches.value_of("announce-address") { + announce_addr.to_string() + } else { + listening_address.to_string() + }; + + let upgraded_config = config + .with_custom_version(to_version.to_string().as_ref()) + .with_listening_address(listening_address) + .with_announce_address(announce_address); + + upgraded_config.save_to_file(None).unwrap_or_else(|err| { + eprintln!("failed to overwrite config file! - {:?}", err); + fail_upgrade(&config_version, &to_version) }); print_successful_upgrade(config_version, to_version); @@ -235,7 +301,15 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version config = match config_version.major { 0 => match config_version.minor { 9 => minor_010_upgrade(config, matches, &config_version, &package_version), - 10 => patch_010_upgrade(config, matches, &config_version, &package_version), + 10 => match config_version.patch { + 0 => patch_010_upgrade(config, matches, &config_version, &package_version), + _ => undetermined_version_upgrade( + config, + matches, + &config_version, + &package_version, + ), + }, _ => unsupported_upgrade(config_version, package_version), }, _ => unsupported_upgrade(config_version, package_version), diff --git a/mixnode/src/commands/upgrade.rs b/mixnode/src/commands/upgrade.rs index 89940e24a0..847e407306 100644 --- a/mixnode/src/commands/upgrade.rs +++ b/mixnode/src/commands/upgrade.rs @@ -10,12 +10,19 @@ use clap::{App, Arg, ArgMatches}; use config::NymConfig; use crypto::asymmetric::identity; use std::fmt::Display; +use std::net::SocketAddr; use std::path::PathBuf; use std::process; +use std::str::FromStr; use version_checker::{parse_version, Version}; const CURRENT_VERSION_ARG_NAME: &str = "current-version"; +fn fail_upgrade(from_version: D1, to_version: D2) -> ! { + print_failed_upgrade(from_version, to_version); + process::exit(1) +} + fn print_start_upgrade(from: D1, to: D2) { println!( "\n==================\nTrying to upgrade mixnode from {} to {} ...", @@ -126,28 +133,24 @@ fn pre_090_upgrade(from: &str, config: Config) -> Config { 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"); - print_failed_upgrade(&from_version, &to_version); - process::exit(1) + 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"); - print_failed_upgrade(&from_version, &to_version); - process::exit(1) + fail_upgrade(&from_version, &to_version) } if config.get_private_identity_key_file() != missing_string_value::() || config.get_public_identity_key_file() != missing_string_value::() { eprintln!("existing config seems to have specified identity keys which were only introduced in 0.9.0! Can't perform upgrade."); - print_failed_upgrade(&from_version, &to_version); - process::exit(1); + fail_upgrade(&from_version, &to_version) } if config.get_validator_rest_endpoints()[0] != missing_string_value::() { eprintln!("existing config seems to have specified new validator rest endpoint which was only introduced in 0.9.0! Can't perform upgrade."); - print_failed_upgrade(&from_version, &to_version); - process::exit(1); + fail_upgrade(&from_version, &to_version) } let mut upgraded_config = config @@ -178,8 +181,7 @@ fn pre_090_upgrade(from: &str, config: Config) -> Config { upgraded_config.save_to_file(None).unwrap_or_else(|err| { eprintln!("failed to overwrite config file! - {:?}", err); - print_failed_upgrade(&from_version, &to_version); - process::exit(1); + fail_upgrade(&from_version, &to_version) }); print_successful_upgrade(from_version, to_version); @@ -203,8 +205,7 @@ fn minor_010_upgrade( if config.get_validator_mixnet_contract_address() != MISSING_VALUE { eprintln!("existing config seems to have specified mixnet contract address which was only introduced in 0.10.0! Can't perform upgrade."); - print_failed_upgrade(&config_version, &to_version); - process::exit(1); + fail_upgrade(&config_version, to_version) } println!( @@ -224,8 +225,7 @@ fn minor_010_upgrade( upgraded_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); + fail_upgrade(&config_version, &to_version) }); print_successful_upgrade(config_version, to_version); @@ -249,8 +249,56 @@ fn patch_010_upgrade( upgraded_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); + fail_upgrade(&config_version, to_version) + }); + + print_successful_upgrade(config_version, to_version); + + upgraded_config +} + +// TODO: to be renamed once the release version is decided (so presumably either 0.10.2 or 0.11.0) +fn undetermined_version_upgrade( + config: Config, + _matches: &ArgMatches, + config_version: &Version, + package_version: &Version, +) -> Config { + // If we decide this version should be tagged with 0.11.0, then the following code will be used instead: + // let to_version = if package_version.major == 0 && package_version.minor == 11 { + // package_version.clone() + // } else { + // Version::new(0, 11, 0) + // }; + let to_version = package_version; + + print_start_upgrade(&config_version, &to_version); + + 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::>(); + if announce_split.len() != 2 { + eprintln!("failed to correctly parse current announce host"); + fail_upgrade(&config_version, &to_version) + } + ( + announce_split[0].to_string(), + announce_split[1].parse().unwrap(), + ) + } + }; + + let upgraded_config = config + .with_custom_version(to_version.to_string().as_ref()) + .with_announce_address(announce_address) + .with_mix_port(custom_mix_port); + + upgraded_config.save_to_file(None).unwrap_or_else(|err| { + eprintln!("failed to overwrite config file! - {:?}", err); + fail_upgrade(&config_version, to_version) }); print_successful_upgrade(config_version, to_version); @@ -270,7 +318,15 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version config = match config_version.major { 0 => match config_version.minor { 9 => minor_010_upgrade(config, matches, &config_version, &package_version), - 10 => patch_010_upgrade(config, matches, &config_version, &package_version), + 10 => match config_version.patch { + 0 => patch_010_upgrade(config, matches, &config_version, &package_version), + _ => undetermined_version_upgrade( + config, + matches, + &config_version, + &package_version, + ), + }, _ => unsupported_upgrade(config_version, package_version), }, _ => unsupported_upgrade(config_version, package_version),