From b059d32485712a63a8bd87fcae22f9c0bde945e2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 23 Jan 2016 23:53:20 +0100 Subject: [PATCH] Argument parsing from CLI. Closes #179 --- Cargo.toml | 1 + res/ethereum/frontier.json | 5 +++++ src/bin/client/main.rs | 45 +++++++++++++++++++++++++++++++++---- src/lib.rs | 2 ++ src/service.rs | 9 ++++++-- src/spec.rs | 12 +++++++++- util/src/network/host.rs | 10 +-------- util/src/network/service.rs | 7 +++--- 8 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 04c4bf956..75f983253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ time = "0.1" evmjit = { path = "rust-evmjit", optional = true } ethash = { path = "ethash" } num_cpus = "0.2" +docopt = "0.6" [features] jit = ["evmjit"] diff --git a/res/ethereum/frontier.json b/res/ethereum/frontier.json index eaf0ef4c1..9cb456ce8 100644 --- a/res/ethereum/frontier.json +++ b/res/ethereum/frontier.json @@ -26,6 +26,11 @@ "gasLimit": "0x1388", "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" }, + "nodes": [ + "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", + "enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303", + "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303" + ], "accounts": { "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 3335d8a72..0d0368480 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -1,6 +1,10 @@ +#![feature(plugin)] +//#![plugin(docopt_macros)] + +extern crate docopt; +extern crate rustc_serialize; extern crate ethcore_util as util; extern crate ethcore; -extern crate rustc_serialize; extern crate log; extern crate env_logger; @@ -14,8 +18,27 @@ use ethcore::service::ClientService; use ethcore::ethereum; use ethcore::blockchain::CacheSize; use ethcore::sync::*; +use docopt::Docopt; -fn setup_log() { +const USAGE: &'static str = " +Parity. Ethereum Client. + +Usage: + parity [options] + parity [options] ... + +Options: + -l --logging LOGGING Specify the logging level + -h --help Show this screen. +"; + +#[derive(Debug, RustcDecodable)] +struct Args { + arg_enode: Option>, + flag_logging: Option, +} + +fn setup_log(init: &Option) { let mut builder = LogBuilder::new(); builder.filter(None, LogLevelFilter::Info); @@ -23,14 +46,28 @@ fn setup_log() { builder.parse(&env::var("RUST_LOG").unwrap()); } + if let &Some(ref x) = init { + builder.parse(x); + } + builder.init().unwrap(); } fn main() { - setup_log(); + let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); + + setup_log(&args.flag_logging); + let spec = ethereum::new_frontier(); - let mut service = ClientService::start(spec).unwrap(); + + let init_nodes = match &args.arg_enode { + &None => spec.nodes().clone(), + &Some(ref enodes) => enodes.clone(), + }; + + let mut service = ClientService::start(spec, &init_nodes).unwrap(); let io_handler = Box::new(ClientIoHandler { client: service.client(), timer: 0, info: Default::default() }); + service.io().register_handler(io_handler).expect("Error registering IO handler"); loop { let mut cmd = String::new(); diff --git a/src/lib.rs b/src/lib.rs index a5b6c3dae..a25fa9338 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,6 +89,8 @@ extern crate evmjit; #[macro_use] extern crate ethcore_util as util; +// NOTE: Add doc parser exception for these pub declarations. + /// TODO [Gav Wood] Please document me pub mod common; /// TODO [Tomusdrw] Please document me diff --git a/src/service.rs b/src/service.rs index 30565b37a..07ff4873c 100644 --- a/src/service.rs +++ b/src/service.rs @@ -13,8 +13,8 @@ pub struct ClientService { impl ClientService { /// Start the service in a separate thread. - pub fn start(spec: Spec) -> Result { - let mut net_service = try!(NetworkService::start()); + pub fn start(spec: Spec, init_nodes: &Vec) -> Result { + let mut net_service = try!(NetworkService::start(init_nodes)); info!("Starting {}", net_service.host_info()); info!("Configured for {} using {} engine", spec.name, spec.engine_name); let mut dir = env::home_dir().unwrap(); @@ -33,6 +33,11 @@ impl ClientService { }) } + /// Get the network service. + pub fn add_node(&mut self, _enode: &str) { + unimplemented!(); + } + /// TODO [arkpar] Please document me pub fn io(&mut self) -> &mut IoService { self.net_service.io() diff --git a/src/spec.rs b/src/spec.rs index 24c0e4eda..bb47edacf 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -73,6 +73,9 @@ pub struct Spec { /// TODO [Gav Wood] Please document me pub engine_name: String, + /// Known nodes on the network in enode format. + pub nodes: Vec, + // Parameters concerning operation of the specific engine we're using. // Name -> RLP-encoded value /// TODO [Gav Wood] Please document me @@ -127,6 +130,9 @@ impl Spec { self.state_root_memo.read().unwrap().as_ref().unwrap().clone() } + /// Get the known knodes of the network in enode format. + pub fn nodes(&self) -> &Vec { &self.nodes } + /// TODO [Gav Wood] Please document me pub fn genesis_header(&self) -> Header { Header { @@ -196,6 +202,10 @@ impl FromJson for Spec { } } + let nodes = if let Some(&Json::Array(ref ns)) = json.find("nodes") { + ns.iter().filter_map(|n| if let &Json::String(ref s) = n { Some(s.to_string()) } else {None}).collect() + } else { Vec::new() }; + let genesis = &json["genesis"];//.as_object().expect("No genesis object in JSON"); let (seal_fields, seal_rlp) = { @@ -212,12 +222,12 @@ impl FromJson for Spec { ) } }; - Spec { name: json.find("name").map(|j| j.as_string().unwrap()).unwrap_or("unknown").to_string(), engine_name: json["engineName"].as_string().unwrap().to_string(), engine_params: json_to_rlp_map(&json["params"]), + nodes: nodes, builtins: builtins, parent_hash: H256::from_str(&genesis["parentHash"].as_string().unwrap()[2..]).unwrap(), author: Address::from_str(&genesis["author"].as_string().unwrap()[2..]).unwrap(), diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 37b58f1f0..67a9c56db 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -259,7 +259,7 @@ impl Host where Message: Send { } } - fn add_node(&mut self, id: &str) { + pub fn add_node(&mut self, id: &str) { match Node::from_str(id) { Err(e) => { warn!("Could not add node: {:?}", e); }, Ok(n) => { @@ -560,14 +560,6 @@ impl IoHandler> for Host where Messa io.event_loop.timeout_ms(Token(NODETABLE_MAINTAIN), 7200).unwrap(); let port = self.info.config.listen_address.port(); self.info.listen_port = port; - - self.add_node("enode://a9a921de2ff09a9a4d38b623c67b2d6b477a8e654ae95d874750cbbcb31b33296496a7b4421934e2629269e180823e52c15c2b19fc59592ec51ffe4f2de76ed7@127.0.0.1:30303"); -/* // GO bootnodes - self.add_node("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"); // IE - self.add_node("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"); // BR - self.add_node("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"); // SG - // ETH/DEV cpp-ethereum (poc-9.ethdev.com) - self.add_node("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303");*/ } fn stream_hup<'s>(&'s mut self, io: &mut IoContext<'s, NetworkIoMessage>, stream: StreamToken) { diff --git a/util/src/network/service.rs b/util/src/network/service.rs index 4c333b8af..c5083e981 100644 --- a/util/src/network/service.rs +++ b/util/src/network/service.rs @@ -13,9 +13,10 @@ pub struct NetworkService where Message: Send + 'static { impl NetworkService where Message: Send + 'static { /// Starts IO event loop - pub fn start() -> Result, UtilError> { + pub fn start(init_nodes: &Vec) -> Result, UtilError> { let mut io_service = try!(IoService::>::start()); - let host = Box::new(Host::new()); + let mut host = Box::new(Host::new()); + for n in init_nodes { host.add_node(&n); } let host_info = host.info.client_version.clone(); info!("NetworkService::start(): id={:?}", host.info.id()); try!(io_service.register_handler(host)); @@ -55,7 +56,5 @@ impl NetworkService where Message: Send + 'static { pub fn io(&mut self) -> &mut IoService> { &mut self.io_service } - - }