More builder methods, incl. announce host/port parsers
This commit is contained in:
Generated
+2
@@ -1449,12 +1449,14 @@ dependencies = [
|
||||
"built",
|
||||
"clap",
|
||||
"config",
|
||||
"crypto",
|
||||
"curve25519-dalek",
|
||||
"directory-client",
|
||||
"dirs",
|
||||
"dotenv",
|
||||
"futures 0.3.1",
|
||||
"log",
|
||||
"pemstore",
|
||||
"pretty_env_logger",
|
||||
"serde",
|
||||
"sphinx",
|
||||
|
||||
@@ -22,7 +22,9 @@ tokio = { version = "0.2", features = ["full"] }
|
||||
## internal
|
||||
addressing = {path = "../common/addressing" }
|
||||
config = {path = "../common/config"}
|
||||
crypto = {path = "../common/crypto"}
|
||||
directory-client = { path = "../common/clients/directory-client" }
|
||||
pemstore = {path = "../common/pemstore"}
|
||||
|
||||
## will be moved to proper dependencies once released
|
||||
sphinx = { git = "https://github.com/nymtech/sphinx", rev="5862939c52e4dd76f836856a01787faec32152b4" }
|
||||
|
||||
@@ -2,23 +2,95 @@ use clap::{App, Arg, ArgMatches};
|
||||
use config::NymConfig;
|
||||
|
||||
pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
|
||||
App::new("init").about("Initialise the mixnode").arg(
|
||||
Arg::with_name("id")
|
||||
.long("id")
|
||||
.help("Id of the nym-mixnode we want to create config for.")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
App::new("init")
|
||||
.about("Initialise the mixnode")
|
||||
.arg(
|
||||
Arg::with_name("id")
|
||||
.long("id")
|
||||
.help("Id of the nym-mixnode we want to create config for.")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("layer")
|
||||
.long("layer")
|
||||
.help("The mixnet layer of this particular node")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("host")
|
||||
.long("host")
|
||||
.help("The custom host on which the mixnode will be running")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("port")
|
||||
.long("port")
|
||||
.help("The port on which the mixnode will be listening")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("announce-host")
|
||||
.long("announce-host")
|
||||
.help("The host that will be reported to the directory server")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("announce-port")
|
||||
.long("announce-port")
|
||||
.help("The port that will be reported to the directory server")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("directory")
|
||||
.long("directory")
|
||||
.help("Address of the directory server the node is sending presence and metrics to")
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn execute(matches: &ArgMatches) {
|
||||
println!("Initialising mixnode...");
|
||||
|
||||
let id = matches.value_of("id").unwrap(); // required for now
|
||||
let mut config = crate::config::Config::new(id);
|
||||
let id = matches.value_of("id").unwrap();
|
||||
let layer = matches.value_of("layer").unwrap().parse().unwrap();
|
||||
let mut config = crate::config::Config::new(id, layer);
|
||||
|
||||
// overriding config defaults here
|
||||
|
||||
if let Some(host) = matches.value_of("host") {
|
||||
config = config.with_listening_host(host);
|
||||
}
|
||||
|
||||
if let Some(port) = matches.value_of("port").map(|port| port.parse::<u16>()) {
|
||||
if let Err(err) = port {
|
||||
// if port was overridden, it must be parsable
|
||||
panic!("Invalid port value provided - {:?}", err);
|
||||
}
|
||||
config = config.with_listening_port(port.unwrap());
|
||||
}
|
||||
|
||||
if let Some(directory) = matches.value_of("directory") {
|
||||
config = config.with_custom_directory(directory);
|
||||
}
|
||||
|
||||
if let Some(announce_host) = matches.value_of("announce-host") {
|
||||
config = config.with_announce_host(announce_host);
|
||||
}
|
||||
|
||||
if let Some(announce_port) = matches
|
||||
.value_of("announce-port")
|
||||
.map(|port| port.parse::<u16>())
|
||||
{
|
||||
if let Err(err) = announce_port {
|
||||
// if port was overridden, it must be parsable
|
||||
panic!("Invalid port value provided - {:?}", err);
|
||||
}
|
||||
config = config.with_announce_port(announce_port.unwrap());
|
||||
}
|
||||
|
||||
let config_save_location = config.get_config_file_save_location();
|
||||
config
|
||||
.save_to_file(None)
|
||||
|
||||
+103
-3
@@ -1,7 +1,10 @@
|
||||
use crate::config::template::config_template;
|
||||
use config::NymConfig;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use log::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
mod template;
|
||||
|
||||
@@ -52,8 +55,8 @@ impl NymConfig for Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new<S: Into<String>>(id: S) -> Self {
|
||||
Config::default().with_id(id)
|
||||
pub fn new<S: Into<String>>(id: S, layer: usize) -> Self {
|
||||
Config::default().with_id(id).with_layer(layer)
|
||||
}
|
||||
|
||||
// builder methods
|
||||
@@ -76,6 +79,86 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_layer(mut self, layer: usize) -> Self {
|
||||
self.mixnode.layer = layer;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_custom_directory<S: Into<String>>(mut self, directory_server: S) -> Self {
|
||||
self.mixnode.directory_server = directory_server.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_listening_host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
// see if the provided `host` is just an ip address or ip:port
|
||||
let host = host.into();
|
||||
|
||||
// is it ip:port?
|
||||
match SocketAddr::from_str(host.as_ref()) {
|
||||
Ok(socket_addr) => {
|
||||
self.mixnode.listening_address = socket_addr;
|
||||
self
|
||||
}
|
||||
// try just for ip
|
||||
Err(_) => match IpAddr::from_str(host.as_ref()) {
|
||||
Ok(ip_addr) => {
|
||||
self.mixnode.listening_address.set_ip(ip_addr);
|
||||
self
|
||||
}
|
||||
Err(_) => {
|
||||
error!(
|
||||
"failed to make any changes to config - invalid host {}",
|
||||
host
|
||||
);
|
||||
self
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_listening_port(mut self, port: u16) -> Self {
|
||||
self.mixnode.listening_address.set_port(port);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_announce_host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
// this is slightly more complicated as we store announce information as String,
|
||||
// since it might not necessarily be a valid SocketAddr (say `nymtech.net:8080` is a valid
|
||||
// announce address, yet invalid SocketAddr`
|
||||
|
||||
// first lets see if we received host:port or just host part of an address
|
||||
let host = host.into();
|
||||
let split_host: Vec<_> = host.split(':').collect();
|
||||
match split_host.len() {
|
||||
1 => {
|
||||
// we provided only 'host' part so we are going to reuse existing port
|
||||
self.mixnode.announce_address =
|
||||
format!("{}:{}", host, self.mixnode.listening_address.port());
|
||||
self
|
||||
}
|
||||
2 => {
|
||||
// we provided 'host:port' so just put the whole thing there
|
||||
self.mixnode.announce_address = host;
|
||||
self
|
||||
}
|
||||
_ => {
|
||||
// we provided something completely invalid, so don't try to parse it
|
||||
error!(
|
||||
"failed to make any changes to config - invalid announce host {}",
|
||||
host
|
||||
);
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_announce_port(mut self, port: u16) -> Self {
|
||||
let current_host: Vec<_> = self.mixnode.announce_address.split(':').collect();
|
||||
debug_assert_eq!(current_host.len(), 2);
|
||||
self.mixnode.announce_address = format!("{}:{}", current_host[0], port);
|
||||
self
|
||||
}
|
||||
|
||||
// getters
|
||||
pub fn get_config_file_save_location(&self) -> PathBuf {
|
||||
self.config_directory().join(Self::config_file_name())
|
||||
@@ -103,6 +186,20 @@ pub struct MixNode {
|
||||
/// URL to the directory server.
|
||||
directory_server: String,
|
||||
|
||||
/// Layer of this particular mixnode determining its position in the network.
|
||||
layer: usize,
|
||||
|
||||
/// Socket address to which this mixnode will bind to and will be listening for packets.
|
||||
listening_address: SocketAddr,
|
||||
|
||||
/// Optional address announced to the directory server for the clients to connect to.
|
||||
/// It is useful, say, in NAT scenarios or wanting to more easily update actual IP address
|
||||
/// later on by using name resolvable with a DNS query, such as `nymtech.net:8080`.
|
||||
/// Additionally a custom port can be provided, so both `nymtech.net:8080` and `nymtech.net`
|
||||
/// are valid announce addresses, while the later will default to whatever port is used for
|
||||
/// `listening_address`.
|
||||
announce_address: String,
|
||||
|
||||
/// Path to file containing private identity key.
|
||||
private_identity_key_file: PathBuf,
|
||||
|
||||
@@ -138,6 +235,9 @@ impl Default for MixNode {
|
||||
MixNode {
|
||||
id: "".to_string(),
|
||||
directory_server: Self::default_directory_server(),
|
||||
layer: 0,
|
||||
listening_address: "0.0.0.0:1789".parse().unwrap(),
|
||||
announce_address: "127.0.0.1789".to_string(),
|
||||
private_identity_key_file: Default::default(),
|
||||
public_identity_key_file: Default::default(),
|
||||
nym_root_directory: Config::default_root_directory(),
|
||||
|
||||
Reference in New Issue
Block a user