diff --git a/parity/main.rs b/parity/main.rs index 460922b64..903b471c5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -36,6 +36,7 @@ extern crate ethcore_rpc as rpc; use std::net::{SocketAddr}; use std::env; +use std::path::PathBuf; use rlog::{LogLevelFilter}; use env_logger::LogBuilder; use ctrlc::CtrlC; @@ -207,6 +208,9 @@ fn main() { net_settings.listen_address = listen; net_settings.public_address = public; net_settings.use_secret = conf.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).expect("Invalid key string")); + let mut net_path = PathBuf::from(&conf.path()); + net_path.push("network"); + net_settings.config_path = Some(net_path.to_str().unwrap().to_owned()); // Build client let mut service = ClientService::start(spec, net_settings, &Path::new(&conf.path())).unwrap(); diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 7366e129b..fb3bcee62 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -21,6 +21,9 @@ use std::str::{FromStr}; use std::sync::*; use std::ops::*; use std::cmp::min; +use std::path::{Path, PathBuf}; +use std::io::{Read, Write}; +use std::fs; use mio::*; use mio::tcp::*; use target_info::Target; @@ -340,7 +343,19 @@ impl Host where Message: Send + Sync + Clone { let addr = config.listen_address; // Setup the server socket let tcp_listener = TcpListener::bind(&addr).unwrap(); - let keys = if let Some(ref secret) = config.use_secret { KeyPair::from_secret(secret.clone()).unwrap() } else { KeyPair::create().unwrap() }; + let keys = if let Some(ref secret) = config.use_secret { + KeyPair::from_secret(secret.clone()).unwrap() + } else { + config.config_path.clone().and_then(|ref p| load_key(&Path::new(&p))) + .map_or_else(|| { + let key = KeyPair::create().unwrap(); + if let Some(path) = config.config_path.clone() { + save_key(&Path::new(&path), &key.secret()); + } + key + }, + |s| KeyPair::from_secret(s).expect("Error creating node secret key")) + }; let endpoint = NodeEndpoint { address: addr.clone(), udp_port: addr.port() }; let discovery = Discovery::new(&keys, endpoint, DISCOVERY); let path = config.config_path.clone(); @@ -914,3 +929,49 @@ impl IoHandler> for Host where Messa } } } + +fn save_key(path: &Path, key: &Secret) { + let mut path_buf = PathBuf::from(path); + if let Err(e) = fs::create_dir_all(path_buf.as_path()) { + warn!("Error creating key directory: {:?}", e); + return; + }; + path_buf.push("key"); + let mut file = match fs::File::create(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + warn!("Error creating key file: {:?}", e); + return; + } + }; + if let Err(e) = file.write(&key.hex().into_bytes()) { + warn!("Error writing key file: {:?}", e); + } +} + +fn load_key(path: &Path) -> Option { + let mut path_buf = PathBuf::from(path); + path_buf.push("key"); + let mut file = match fs::File::open(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + debug!("Error opening key file: {:?}", e); + return None; + } + }; + let mut buf = String::new(); + match file.read_to_string(&mut buf) { + Ok(_) => {}, + Err(e) => { + warn!("Error reading key file: {:?}", e); + return None; + } + } + match Secret::from_str(&buf) { + Ok(key) => Some(key), + Err(e) => { + warn!("Error parsing key file: {:?}", e); + None + } + } +} diff --git a/util/src/network/node_table.rs b/util/src/network/node_table.rs index 2b02748b4..e5c47cafb 100644 --- a/util/src/network/node_table.rs +++ b/util/src/network/node_table.rs @@ -273,7 +273,7 @@ impl NodeTable { let mut file = match fs::File::open(path_buf.as_path()) { Ok(file) => file, Err(e) => { - warn!("Error opening node table file: {:?}", e); + debug!("Error opening node table file: {:?}", e); return nodes; } };