Better user errors.
Fixed up README.
This commit is contained in:
parent
1cd76de8ba
commit
2cc690f31f
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -12,7 +12,9 @@ dependencies = [
|
|||||||
"ethcore-util 0.9.99",
|
"ethcore-util 0.9.99",
|
||||||
"ethsync 0.9.99",
|
"ethsync 0.9.99",
|
||||||
"fdlimit 0.1.0",
|
"fdlimit 0.1.0",
|
||||||
|
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -19,6 +19,8 @@ ethcore-rpc = { path = "rpc", optional = true }
|
|||||||
fdlimit = { path = "util/fdlimit" }
|
fdlimit = { path = "util/fdlimit" }
|
||||||
target_info = "0.1"
|
target_info = "0.1"
|
||||||
daemonize = "0.2"
|
daemonize = "0.2"
|
||||||
|
regex = "0.1"
|
||||||
|
lazy_static = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rpc"]
|
default = ["rpc"]
|
||||||
|
@ -50,7 +50,7 @@ cd ..
|
|||||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
|
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
|
||||||
|
|
||||||
# install beta and make it default
|
# install beta and make it default
|
||||||
sudo multirust default beta
|
multirust default beta
|
||||||
|
|
||||||
# download and build parity
|
# download and build parity
|
||||||
git clone https://github.com/ethcore/parity
|
git clone https://github.com/ethcore/parity
|
||||||
|
@ -26,17 +26,21 @@ extern crate ethcore;
|
|||||||
extern crate ethsync;
|
extern crate ethsync;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log as rlog;
|
extern crate log as rlog;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate ctrlc;
|
extern crate ctrlc;
|
||||||
extern crate fdlimit;
|
extern crate fdlimit;
|
||||||
extern crate target_info;
|
extern crate target_info;
|
||||||
extern crate daemonize;
|
extern crate daemonize;
|
||||||
|
extern crate regex;
|
||||||
|
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
extern crate ethcore_rpc as rpc;
|
extern crate ethcore_rpc as rpc;
|
||||||
|
|
||||||
use std::net::{SocketAddr};
|
use std::net::{SocketAddr};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::process::exit;
|
||||||
use rlog::{LogLevelFilter};
|
use rlog::{LogLevelFilter};
|
||||||
use env_logger::LogBuilder;
|
use env_logger::LogBuilder;
|
||||||
use ctrlc::CtrlC;
|
use ctrlc::CtrlC;
|
||||||
@ -51,6 +55,7 @@ use ethsync::EthSync;
|
|||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use target_info::Target;
|
use target_info::Target;
|
||||||
use daemonize::Daemonize;
|
use daemonize::Daemonize;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
const USAGE: &'static str = "
|
const USAGE: &'static str = "
|
||||||
Parity. Ethereum Client.
|
Parity. Ethereum Client.
|
||||||
@ -150,6 +155,16 @@ By Wood/Paronyan/Kotewicz/Drwięga/Volf.\
|
|||||||
", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os());
|
", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn die_with_message(msg: &str) -> ! {
|
||||||
|
println!("ERROR: {}", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! die {
|
||||||
|
($($arg:tt)*) => (die_with_message(&format!("{}", format_args!($($arg)*))));
|
||||||
|
}
|
||||||
|
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
args: Args
|
args: Args
|
||||||
}
|
}
|
||||||
@ -174,7 +189,17 @@ impl Configuration {
|
|||||||
"frontier" | "mainnet" => ethereum::new_frontier(),
|
"frontier" | "mainnet" => ethereum::new_frontier(),
|
||||||
"morden" | "testnet" => ethereum::new_morden(),
|
"morden" | "testnet" => ethereum::new_morden(),
|
||||||
"olympic" => ethereum::new_olympic(),
|
"olympic" => ethereum::new_olympic(),
|
||||||
f => Spec::from_json_utf8(contents(f).expect("Couldn't read chain specification file. Sure it exists?").as_ref()),
|
f => Spec::from_json_utf8(contents(f).unwrap_or_else(|_| die!("{}: Couldn't read chain specification file. Sure it exists?", f)).as_ref()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_enode(e: &str) -> Option<String> {
|
||||||
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new(r"^enode://([0-9a-fA-F]{64})@(\d+\.\d+\.\d+\.\d+):(\d+)$").unwrap();
|
||||||
|
}
|
||||||
|
match RE.is_match(e) {
|
||||||
|
true => Some(e.to_owned()),
|
||||||
|
false => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +207,7 @@ impl Configuration {
|
|||||||
if self.args.flag_no_bootstrap { Vec::new() } else {
|
if self.args.flag_no_bootstrap { Vec::new() } else {
|
||||||
match self.args.arg_enode.len() {
|
match self.args.arg_enode.len() {
|
||||||
0 => spec.nodes().clone(),
|
0 => spec.nodes().clone(),
|
||||||
_ => self.args.arg_enode.clone(), // TODO check format first.
|
_ => self.args.arg_enode.iter().map(|s| Self::normalize_enode(s).unwrap_or_else(||die!("{}: Invalid node address format given for a boot node.", s))).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +222,7 @@ impl Configuration {
|
|||||||
public_address = SocketAddr::from_str(self.args.flag_public_address.as_ref()).expect("Invalid public address given with --public-address");
|
public_address = SocketAddr::from_str(self.args.flag_public_address.as_ref()).expect("Invalid public address given with --public-address");
|
||||||
}
|
}
|
||||||
Some(ref a) => {
|
Some(ref a) => {
|
||||||
public_address = SocketAddr::from_str(a.as_ref()).expect("Invalid listen/public address given with --address");
|
public_address = SocketAddr::from_str(a.as_ref()).unwrap_or_else(|_|die!("{}: Invalid listen/public address given with --address", a));
|
||||||
listen_address = public_address;
|
listen_address = public_address;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -205,17 +230,28 @@ impl Configuration {
|
|||||||
(listen_address, public_address)
|
(listen_address, public_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn net_settings(&self, spec: &Spec) -> NetworkConfiguration {
|
||||||
|
let mut ret = NetworkConfiguration::new();
|
||||||
|
ret.nat_enabled = self.args.flag_upnp;
|
||||||
|
ret.boot_nodes = self.init_nodes(spec);
|
||||||
|
let (listen, public) = self.net_addresses();
|
||||||
|
ret.listen_address = listen;
|
||||||
|
ret.public_address = public;
|
||||||
|
ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).unwrap_or_else(|_| s.as_bytes().sha3()));
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
fn execute(&self) {
|
fn execute(&self) {
|
||||||
if self.args.flag_version {
|
if self.args.flag_version {
|
||||||
print_version();
|
print_version();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.args.cmd_daemon {
|
if self.args.cmd_daemon {
|
||||||
let daemonize = Daemonize::new().pid_file(self.args.arg_pid_file.clone()).chown_pid_file(true);
|
Daemonize::new()
|
||||||
match daemonize.start() {
|
.pid_file(self.args.arg_pid_file.clone())
|
||||||
Ok(_) => info!("Daemonized"),
|
.chown_pid_file(true)
|
||||||
Err(e) => { error!("{}", e); return; },
|
.start()
|
||||||
}
|
.unwrap_or_else(|e| die!("Couldn't daemonize; {}", e));
|
||||||
}
|
}
|
||||||
self.execute_client();
|
self.execute_client();
|
||||||
}
|
}
|
||||||
@ -227,15 +263,7 @@ impl Configuration {
|
|||||||
unsafe { ::fdlimit::raise_fd_limit(); }
|
unsafe { ::fdlimit::raise_fd_limit(); }
|
||||||
|
|
||||||
let spec = self.spec();
|
let spec = self.spec();
|
||||||
|
let net_settings = self.net_settings(&spec);
|
||||||
// Configure network
|
|
||||||
let mut net_settings = NetworkConfiguration::new();
|
|
||||||
net_settings.nat_enabled = self.args.flag_upnp;
|
|
||||||
net_settings.boot_nodes = self.init_nodes(&spec);
|
|
||||||
let (listen, public) = self.net_addresses();
|
|
||||||
net_settings.listen_address = listen;
|
|
||||||
net_settings.public_address = public;
|
|
||||||
net_settings.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).expect("Invalid key string"));
|
|
||||||
|
|
||||||
// Build client
|
// Build client
|
||||||
let mut service = ClientService::start(spec, net_settings, &Path::new(&self.path())).unwrap();
|
let mut service = ClientService::start(spec, net_settings, &Path::new(&self.path())).unwrap();
|
||||||
@ -265,11 +293,13 @@ impl Configuration {
|
|||||||
|
|
||||||
fn wait_for_exit(client_service: &ClientService) {
|
fn wait_for_exit(client_service: &ClientService) {
|
||||||
let exit = Arc::new(Condvar::new());
|
let exit = Arc::new(Condvar::new());
|
||||||
|
|
||||||
// Handle possible exits
|
// Handle possible exits
|
||||||
let e = exit.clone();
|
let e = exit.clone();
|
||||||
CtrlC::set_handler(move || { e.notify_all(); });
|
CtrlC::set_handler(move || { e.notify_all(); });
|
||||||
let e = exit.clone();
|
let e = exit.clone();
|
||||||
client_service.on_panic(move |_reason| { e.notify_all(); });
|
client_service.on_panic(move |_reason| { e.notify_all(); });
|
||||||
|
|
||||||
// Wait for signal
|
// Wait for signal
|
||||||
let mutex = Mutex::new(());
|
let mutex = Mutex::new(());
|
||||||
let _ = exit.wait(mutex.lock().unwrap()).unwrap();
|
let _ = exit.wait(mutex.lock().unwrap()).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user