diff --git a/res/ethereum/tests b/res/ethereum/tests index dc86e6359..e838fd909 160000 --- a/res/ethereum/tests +++ b/res/ethereum/tests @@ -1 +1 @@ -Subproject commit dc86e6359675440aea59ddb48648a01c799925d8 +Subproject commit e838fd90998fc5502d0b7c9427a4c231f9a6953d diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 5c79b7755..e2892693c 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -30,7 +30,13 @@ fn setup_log() { fn main() { setup_log(); let spec = ethereum::new_frontier(); - let mut service = ClientService::start(spec).unwrap(); + let mut net_settings = NetworkConfiguration::new(); + let args: Vec<_> = env::args().collect(); + if args.len() == 2 { + net_settings.boot_nodes.push(args[1].trim_matches('\"').to_string()); + } + + let mut service = ClientService::start(spec, net_settings).unwrap(); let io_handler = Arc::new(ClientIoHandler { client: service.client(), info: Default::default(), sync: service.sync() }); service.io().register_handler(io_handler).expect("Error registering IO handler"); diff --git a/src/client.rs b/src/client.rs index 6f47d0601..4461f3d7b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -162,14 +162,10 @@ impl Client { let db = Arc::new(DB::open(&opts, state_path.to_str().unwrap()).unwrap()); let engine = Arc::new(try!(spec.to_engine())); - { - let mut state_db = JournalDB::new_with_arc(db.clone()); - if engine.spec().ensure_db_good(&mut state_db) { - state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB"); - } + let mut state_db = JournalDB::new_with_arc(db.clone()); + if engine.spec().ensure_db_good(&mut state_db) { + state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB"); } - let state_db = JournalDB::new_with_arc(db); - Ok(Arc::new(Client { chain: chain, engine: engine.clone(), diff --git a/src/service.rs b/src/service.rs index 6ff7d46be..ce2c30720 100644 --- a/src/service.rs +++ b/src/service.rs @@ -26,8 +26,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, net_config: NetworkConfiguration) -> Result { + let mut net_service = try!(NetworkService::start(net_config)); info!("Starting {}", net_service.host_info()); info!("Configured for {} using {} engine", spec.name, spec.engine_name); let mut dir = env::home_dir().unwrap(); diff --git a/util/src/network/connection.rs b/util/src/network/connection.rs index c4c8d29c6..fb7bfb734 100644 --- a/util/src/network/connection.rs +++ b/util/src/network/connection.rs @@ -137,8 +137,8 @@ impl Connection { pub fn register_socket(&self, reg: Token, event_loop: &mut EventLoop) -> io::Result<()> { trace!(target: "net", "connection register; token={:?}", reg); event_loop.register(&self.socket, reg, self.interest, PollOpt::edge() | PollOpt::oneshot()).or_else(|e| { - error!("Failed to register {:?}, {:?}", reg, e); - Err(e) + debug!("Failed to register {:?}, {:?}", reg, e); + Ok(()) }) } @@ -146,8 +146,8 @@ impl Connection { pub fn update_socket(&self, reg: Token, event_loop: &mut EventLoop) -> io::Result<()> { trace!(target: "net", "connection reregister; token={:?}", reg); event_loop.reregister( &self.socket, reg, self.interest, PollOpt::edge() | PollOpt::oneshot()).or_else(|e| { - error!("Failed to reregister {:?}, {:?}", reg, e); - Err(e) + debug!("Failed to reregister {:?}, {:?}", reg, e); + Ok(()) }) } diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 559f69f49..8fffdde69 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -28,22 +28,32 @@ const IDEAL_PEERS: u32 = 10; const MAINTENANCE_TIMEOUT: u64 = 1000; #[derive(Debug)] -struct NetworkConfiguration { - listen_address: SocketAddr, - public_address: SocketAddr, - nat_enabled: bool, - discovery_enabled: bool, - pin: bool, +/// Network service configuration +pub struct NetworkConfiguration { + /// IP address to listen for incoming connections + pub listen_address: SocketAddr, + /// IP address to advertise + pub public_address: SocketAddr, + /// Enable NAT configuration + pub nat_enabled: bool, + /// Enable discovery + pub discovery_enabled: bool, + /// Pin to boot nodes only + pub pin: bool, + /// List of initial node addresses + pub boot_nodes: Vec, } impl NetworkConfiguration { - fn new() -> NetworkConfiguration { + /// Create a new instance of default settings. + pub fn new() -> NetworkConfiguration { NetworkConfiguration { listen_address: SocketAddr::from_str("0.0.0.0:30304").unwrap(), public_address: SocketAddr::from_str("0.0.0.0:30304").unwrap(), nat_enabled: true, discovery_enabled: true, pin: false, + boot_nodes: Vec::new(), } } } @@ -246,8 +256,8 @@ pub struct Host where Message: Send + Sync + Clone { } impl Host where Message: Send + Sync + Clone { - pub fn new() -> Host { - let config = NetworkConfiguration::new(); + /// Create a new instance + pub fn new(config: NetworkConfiguration) -> Host { let addr = config.listen_address; // Setup the server socket let tcp_listener = TcpListener::bind(&addr).unwrap(); @@ -279,13 +289,19 @@ impl Host where Message: Send + Sync + Clone { None => warn!("No public network interface"), */ - // self.add_node("enode://a9a921de2ff09a9a4d38b623c67b2d6b477a8e654ae95d874750cbbcb31b33296496a7b4421934e2629269e180823e52c15c2b19fc59592ec51ffe4f2de76ed7@127.0.0.1:30303"); - // GO bootnodes - host.add_node("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"); // IE - host.add_node("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"); // BR - host.add_node("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"); // SG + let boot_nodes = host.info.read().unwrap().config.boot_nodes.clone(); + if boot_nodes.is_empty() { + // GO bootnodes + host.add_node("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"); // IE + host.add_node("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"); // BR + host.add_node("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"); // SG + } + else { + for n in boot_nodes { + host.add_node(&n); + } + } // ETH/DEV cpp-ethereum (poc-9.ethdev.com) - //host.add_node("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"); host } @@ -517,7 +533,8 @@ impl Host where Message: Send + Sync + Clone { } fn start_session(&self, token: StreamToken, io: &IoContext>) { - self.connections.write().unwrap().replace_with(token, |c| { + let mut connections = self.connections.write().unwrap(); + connections.replace_with(token, |c| { match Arc::try_unwrap(c).ok().unwrap().into_inner().unwrap() { ConnectionEntry::Handshake(h) => { let session = Session::new(h, io, &self.info.read().unwrap()).expect("Session creation error"); diff --git a/util/src/network/mod.rs b/util/src/network/mod.rs index 0c734442d..c175ab0a2 100644 --- a/util/src/network/mod.rs +++ b/util/src/network/mod.rs @@ -40,7 +40,7 @@ /// } /// /// fn main () { -/// let mut service = NetworkService::::start().expect("Error creating network service"); +/// let mut service = NetworkService::::start(NetworkConfiguration::new()).expect("Error creating network service"); /// service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]); /// /// // Wait for quit condition @@ -71,6 +71,7 @@ pub use network::host::NetworkIoMessage; pub use network::host::NetworkIoMessage::User as UserMessage; /// TODO [arkpar] Please document me pub use network::error::NetworkError; +pub use network::host::NetworkConfiguration; use io::TimerToken; @@ -130,6 +131,6 @@ fn test_net_service() { } } - let mut service = NetworkService::::start().expect("Error creating network service"); + let mut service = NetworkService::::start(NetworkConfiguration::new()).expect("Error creating network service"); service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]).unwrap(); } diff --git a/util/src/network/service.rs b/util/src/network/service.rs index 67d2b55e2..8c29a8042 100644 --- a/util/src/network/service.rs +++ b/util/src/network/service.rs @@ -1,6 +1,6 @@ use std::sync::*; use error::*; -use network::{NetworkProtocolHandler}; +use network::{NetworkProtocolHandler, NetworkConfiguration}; use network::error::{NetworkError}; use network::host::{Host, NetworkIoMessage, ProtocolId}; use io::*; @@ -14,9 +14,9 @@ pub struct NetworkService where Message: Send + Sync + Clone + 'static impl NetworkService where Message: Send + Sync + Clone + 'static { /// Starts IO event loop - pub fn start() -> Result, UtilError> { + pub fn start(config: NetworkConfiguration) -> Result, UtilError> { let mut io_service = try!(IoService::>::start()); - let host = Arc::new(Host::new()); + let host = Arc::new(Host::new(config)); let host_info = host.client_version(); info!("NetworkService::start(): id={:?}", host.client_id()); try!(io_service.register_handler(host));