diff --git a/Cargo.toml b/Cargo.toml index 9feb18e08..ee60a704f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,8 +55,7 @@ default = ["ui", "use-precompiled-js"] ui = ["dapps", "ethcore-signer/ui"] use-precompiled-js = ["ethcore-dapps/use-precompiled-js", "ethcore-signer/use-precompiled-js"] dapps = ["ethcore-dapps"] -dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", -"ethcore-dapps/dev", "ethcore-signer/dev"] +dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethcore-dapps/dev", "ethcore-signer/dev"] travis-beta = ["ethcore/json-tests"] travis-nightly = ["ethcore/json-tests", "dev"] @@ -64,6 +63,10 @@ travis-nightly = ["ethcore/json-tests", "dev"] path = "parity/main.rs" name = "parity" +[[bin]] +path = "parity/sync/main.rs" +name = "sync" + [profile.release] debug = true lto = false diff --git a/ethcore/build.rs b/ethcore/build.rs index 9f61851d4..25b559b43 100644 --- a/ethcore/build.rs +++ b/ethcore/build.rs @@ -44,4 +44,18 @@ fn main() { codegen::register(&mut registry); registry.expand("", &intermediate, &dst).unwrap(); } + + // chain notify interface + { + let src = Path::new("src/client/chain_notify.rs"); + let intermediate = Path::new(&out_dir).join("chain_notify.intermediate.rs.in"); + let mut registry = syntex::Registry::new(); + codegen::register(&mut registry); + registry.expand("", &src, &intermediate).unwrap(); + + let dst = Path::new(&out_dir).join("chain_notify.ipc.rs"); + let mut registry = syntex::Registry::new(); + codegen::register(&mut registry); + registry.expand("", &intermediate, &dst).unwrap(); + } } diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index 2b1d8d562..71c076e4c 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -15,8 +15,12 @@ // along with Parity. If not, see . use util::numbers::*; +use ipc::{IpcConfig, BinaryConvertError}; +use std::collections::VecDeque; +use std::mem; /// Represents what has to be handled by actor listening to chain events +#[derive(Ipc)] pub trait ChainNotify : Send + Sync { /// fires when chain has new blocks fn new_blocks(&self, @@ -38,3 +42,5 @@ pub trait ChainNotify : Send + Sync { // does nothing by default } } + +impl IpcConfig for ChainNotify { } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ca4fdde06..92832837a 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1073,4 +1073,4 @@ impl MayPanic for Client { } } -impl IpcConfig for Arc { } +impl IpcConfig for BlockChainClient { } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index a7ad99e80..b8426c9f3 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -20,7 +20,6 @@ mod config; mod error; mod test_client; mod trace; -mod chain_notify; pub use self::client::*; pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockQueueConfig, BlockChainConfig, Switch, VMType}; @@ -60,6 +59,13 @@ pub mod client { include!(concat!(env!("OUT_DIR"), "/client.ipc.rs")); } +pub mod chain_notify { + //! Chain notify interface + + #![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues + include!(concat!(env!("OUT_DIR"), "/chain_notify.ipc.rs")); +} + /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index a2fa0ee49..0849acc0a 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -19,7 +19,6 @@ use syntax::ast::{ MetaItem, Item, ImplItemKind, - ImplItem, MethodSig, Arg, PatKind, @@ -592,8 +591,8 @@ fn push_client_implementation( let handshake_item = quote_impl_item!(cx, pub fn handshake(&self) -> Result<(), ::ipc::Error> { let payload = ::ipc::Handshake { - protocol_version: ::std::sync::Arc::<$endpoint>::protocol_version(), - api_version: ::std::sync::Arc::<$endpoint>::api_version(), + protocol_version: $endpoint::protocol_version(), + api_version: $endpoint::api_version(), }; ::ipc::invoke( @@ -769,7 +768,7 @@ fn ty_ident_map(original_ty: &P) -> IdentMap { ident_map } -/// implements `IpcInterface` for the given class `C` +/// implements `IpcInterface` for the given class `C` fn implement_interface( cx: &ExtCtxt, builder: &aster::AstBuilder, @@ -835,7 +834,7 @@ fn implement_interface( }; let ipc_item = quote_item!(cx, - impl $host_generics ::ipc::IpcInterface<$interface_endpoint> for ::std::sync::Arc<$interface_endpoint> $where_clause { + impl $host_generics ::ipc::IpcInterface for $interface_endpoint $where_clause { fn dispatch(&self, r: &mut R) -> Vec where R: ::std::io::Read { diff --git a/ipc/hypervisor/src/lib.rs b/ipc/hypervisor/src/lib.rs index 69bbbffae..0a4d39390 100644 --- a/ipc/hypervisor/src/lib.rs +++ b/ipc/hypervisor/src/lib.rs @@ -33,52 +33,53 @@ use service::{HypervisorService, IpcModuleId}; use std::process::{Command,Child}; use std::collections::HashMap; -pub use service::{HypervisorServiceClient, CLIENT_MODULE_ID}; +pub use service::{HypervisorServiceClient, CLIENT_MODULE_ID, SYNC_MODULE_ID}; -type BinaryId = &'static str; - -const CLIENT_BINARY: BinaryId = "client"; +pub type BinaryId = &'static str; pub struct Hypervisor { ipc_addr: String, service: Arc, ipc_worker: RwLock>, processes: RwLock>, - db_path: String, + modules: HashMap)>, } impl Hypervisor { /// initializes the Hypervisor service with the open ipc socket for incoming clients - pub fn new(db_path: &str) -> Hypervisor { - Hypervisor::with_url(db_path, HYPERVISOR_IPC_URL) + pub fn new() -> Hypervisor { + Hypervisor::with_url(HYPERVISOR_IPC_URL) } - /// Starts on the specified address for ipc listener - fn with_url(db_path: &str, addr: &str) -> Hypervisor{ - Hypervisor::with_url_and_service(db_path, addr, HypervisorService::new()) + pub fn module(mut self, module_id: IpcModuleId, binary_id: BinaryId, args: Vec) -> Hypervisor { + self.modules.insert(module_id, (binary_id, args)); + self.service.add_module(module_id); + self + } + + pub fn local_module(self, module_id: IpcModuleId) -> Hypervisor { + self.service.add_module(module_id); + self } /// Starts with the specified address for the ipc listener and /// the specified list of modules in form of created service - fn with_url_and_service(db_path: &str, addr: &str, service: Arc) -> Hypervisor { + pub fn with_url(addr: &str) -> Hypervisor { + let service = HypervisorService::new(); let worker = nanoipc::Worker::new(&service); Hypervisor{ ipc_addr: addr.to_owned(), service: service, ipc_worker: RwLock::new(worker), processes: RwLock::new(HashMap::new()), - db_path: db_path.to_owned(), + modules: HashMap::new(), } } /// Since one binary can host multiple modules /// we match binaries - fn match_module(module_id: &IpcModuleId) -> Option { - match *module_id { - CLIENT_MODULE_ID => Some(CLIENT_BINARY), - // none means the module is inside the main binary - _ => None - } + fn match_module(&self, module_id: &IpcModuleId) -> Option<&(BinaryId, Vec)> { + self.modules.get(module_id) } /// Creates IPC listener and starts all binaries @@ -95,7 +96,7 @@ impl Hypervisor { /// Does nothing when it is already started on module is inside the /// main binary fn start_module(&self, module_id: IpcModuleId) { - Self::match_module(&module_id).map(|binary_id| { + self.match_module(&module_id).map(|&(ref binary_id, ref binary_args)| { let mut processes = self.processes.write().unwrap(); { if processes.get(binary_id).is_some() { @@ -108,7 +109,12 @@ impl Hypervisor { executable_path.pop(); executable_path.push(binary_id); - let child = Command::new(&executable_path.to_str().unwrap()).arg(&self.db_path).spawn().unwrap_or_else( + let mut command = Command::new(&executable_path.to_str().unwrap()); + for arg in binary_args { command.arg(arg); } + + trace!(target: "hypervisor", "Spawn executable: {:?}", command); + + let child = command.spawn().unwrap_or_else( |e| panic!("Hypervisor cannot start binary ({:?}): {}", executable_path, e)); processes.insert(binary_id, child); }); @@ -132,7 +138,7 @@ impl Hypervisor { let mut childs = self.processes.write().unwrap(); for (ref mut binary, ref mut child) in childs.iter_mut() { - trace!(target: "hypervisor", "HYPERVISOR: Stopping process module: {}", binary); + trace!(target: "hypervisor", "Stopping process module: {}", binary); child.kill().unwrap(); } } @@ -149,7 +155,6 @@ mod tests { use super::*; use std::sync::atomic::{AtomicBool,Ordering}; use std::sync::Arc; - use super::service::*; use nanoipc; #[test] @@ -157,7 +162,7 @@ mod tests { let url = "ipc:///tmp/test-parity-hypervisor-10.ipc"; let test_module_id = 8080u64; - let hypervisor = Hypervisor::with_url_and_service("", url, HypervisorService::with_modules(vec![test_module_id])); + let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); assert_eq!(false, hypervisor.modules_ready()); } @@ -177,7 +182,7 @@ mod tests { client.module_ready(test_module_id); }); - let hypervisor = Hypervisor::with_url_and_service("", url, HypervisorService::with_modules(vec![test_module_id])); + let hypervisor = Hypervisor::with_url(url).local_module(test_module_id); hypervisor.start(); hypervisor_ready_local.store(true, Ordering::Relaxed); hypervisor.wait_for_startup(); diff --git a/ipc/hypervisor/src/service.rs.in b/ipc/hypervisor/src/service.rs.in index 1e569f5bd..7beffe23f 100644 --- a/ipc/hypervisor/src/service.rs.in +++ b/ipc/hypervisor/src/service.rs.in @@ -26,6 +26,9 @@ pub type IpcModuleId = u64; /// Blockhain database module id pub const CLIENT_MODULE_ID: IpcModuleId = 2000; +/// Sync module id +pub const SYNC_MODULE_ID: IpcModuleId = 2100; + /// IPC service that handles module management pub struct HypervisorService { check_list: RwLock>, @@ -43,7 +46,7 @@ impl HypervisorService { impl HypervisorService { /// New service with the default list of modules pub fn new() -> Arc { - HypervisorService::with_modules(vec![CLIENT_MODULE_ID]) + HypervisorService::with_modules(vec![]) } /// New service with list of modules that will report for being ready @@ -57,6 +60,10 @@ impl HypervisorService { }) } + pub fn add_module(&self, module_id: IpcModuleId) { + self.check_list.write().unwrap().insert(module_id, false); + } + /// Number of modules still being waited for check-in pub fn unchecked_count(&self) -> usize { self.check_list.read().unwrap().iter().filter(|&(_, status)| !status).count() @@ -68,4 +75,4 @@ impl HypervisorService { } } -impl ::ipc::IpcConfig for Arc {} +impl ::ipc::IpcConfig for HypervisorService {} diff --git a/ipc/nano/src/lib.rs b/ipc/nano/src/lib.rs index 9262b3fe8..5fb2faaa7 100644 --- a/ipc/nano/src/lib.rs +++ b/ipc/nano/src/lib.rs @@ -33,7 +33,7 @@ const POLL_TIMEOUT: isize = 100; const CLIENT_CONNECTION_TIMEOUT: isize = 2500; /// Generic worker to handle service (binded) sockets -pub struct Worker where Arc: IpcInterface { +pub struct Worker where S: IpcInterface { service: Arc, sockets: Vec<(Socket, Endpoint)>, polls: Vec, @@ -116,7 +116,7 @@ pub enum SocketError { RequestLink, } -impl Worker where Arc: IpcInterface { +impl Worker where S: IpcInterface { /// New worker over specified `service` pub fn new(service: &Arc) -> Worker { Worker:: { diff --git a/ipc/rpc/src/interface.rs b/ipc/rpc/src/interface.rs index a8d0eba2f..a3c170c2b 100644 --- a/ipc/rpc/src/interface.rs +++ b/ipc/rpc/src/interface.rs @@ -29,7 +29,7 @@ pub struct Handshake { /// Allows to configure custom version and custom handshake response for /// ipc host -pub trait IpcConfig { +pub trait IpcConfig { /// Current service api version /// Should be increased if any of the methods changes signature fn api_version() -> Version { @@ -60,7 +60,7 @@ pub enum Error { /// Allows implementor to be attached to generic worker and dispatch rpc requests /// over IPC -pub trait IpcInterface : IpcConfig { +pub trait IpcInterface : IpcConfig { /// reads the message from io, dispatches the call and returns serialized result fn dispatch(&self, r: &mut R) -> Vec where R: Read; diff --git a/parity/io_handler.rs b/parity/io_handler.rs index da989a000..d0b33a470 100644 --- a/parity/io_handler.rs +++ b/parity/io_handler.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use ethcore::client::Client; use ethcore::service::ClientIoMessage; -use ethsync::{EthSync, SyncProvider, ManageNetwork}; +use ethsync::{SyncProvider, ManageNetwork}; use ethcore::account_provider::AccountProvider; use util::{TimerToken, IoHandler, IoContext}; @@ -27,7 +27,8 @@ const INFO_TIMER: TimerToken = 0; pub struct ClientIoHandler { pub client: Arc, - pub sync: Arc, + pub sync: Arc, + pub net: Arc, pub accounts: Arc, pub info: Informant, } @@ -40,7 +41,7 @@ impl IoHandler for ClientIoHandler { fn timeout(&self, _io: &IoContext, timer: TimerToken) { if let INFO_TIMER = timer { let sync_status = self.sync.status(); - let network_config = self.sync.network_config(); + let network_config = self.net.network_config(); self.info.tick(&self.client, Some((sync_status, network_config))); } } diff --git a/parity/main.rs b/parity/main.rs index fbfa76510..89ca051a2 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -72,6 +72,7 @@ mod migration; mod signer; mod rpc_apis; mod url; +mod modules; use std::io::{Write, Read, BufReader, BufRead}; use std::ops::Deref; @@ -85,12 +86,11 @@ use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, version, journaldb, RotatingLogger}; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; -use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, - ChainNotify, Mode}; +use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, Mode}; use ethcore::error::{ImportError}; use ethcore::service::ClientService; use ethcore::spec::Spec; -use ethsync::{EthSync, NetworkConfiguration}; +use ethsync::{NetworkConfiguration}; use ethcore::miner::{Miner, MinerService, ExternalMiner}; use migration::migrate; use informant::Informant; @@ -243,27 +243,29 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig, let network_settings = Arc::new(conf.network_settings()); // Sync - let sync = EthSync::new(sync_config, client.clone(), NetworkConfiguration::from(net_settings)) - .unwrap_or_else(|e| die_with_error("Sync", ethcore::error::Error::Util(e))); - service.set_notify(&(sync.clone() as Arc)); + let (sync_provider, manage_network, chain_notify) = + modules::sync(sync_config, NetworkConfiguration::from(net_settings), client.clone()) + .unwrap_or_else(|e| die_with_error("Sync", e)); + service.set_notify(&chain_notify); // if network is active by default if match conf.mode() { Mode::Dark(..) => false, _ => !conf.args.flag_no_network } { - sync.start(); + chain_notify.start(); } let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { signer_port: conf.signer_port(), signer_queue: Arc::new(rpc_apis::ConfirmationsQueue::default()), client: client.clone(), - sync: sync.clone(), + sync: sync_provider.clone(), + net: manage_network.clone(), secret_store: account_service.clone(), miner: miner.clone(), external_miner: external_miner.clone(), logger: logger.clone(), settings: network_settings.clone(), allow_pending_receipt_query: !conf.args.flag_geth, - net_service: sync.clone(), + net_service: manage_network.clone(), }); let dependencies = rpc::Dependencies { @@ -311,7 +313,8 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig, let io_handler = Arc::new(ClientIoHandler { client: service.client(), info: Informant::new(conf.have_color()), - sync: sync.clone(), + sync: sync_provider.clone(), + net: manage_network.clone(), accounts: account_service.clone(), }); service.register_io_handler(io_handler).expect("Error registering IO handler"); diff --git a/parity/modules.rs b/parity/modules.rs new file mode 100644 index 000000000..e0960dc6e --- /dev/null +++ b/parity/modules.rs @@ -0,0 +1,40 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use ethsync::{EthSync, SyncProvider, ManageNetwork, SyncConfig, NetworkConfiguration}; +use std::sync::Arc; +use ethcore::client::{ChainNotify, BlockChainClient}; +use ethcore; + +#[cfg(feature="ipc")] +pub fn sync( + sync_cfg: SyncConfig, + net_cfg: NetworkConfiguration, + client: Arc) + -> Result<(Arc, Arc, Arc), ethcore::error::Error> +{ +} + +#[cfg(not(feature="ipc"))] +pub fn sync( + sync_cfg: SyncConfig, + net_cfg: NetworkConfiguration, + client: Arc) + -> Result<(Arc, Arc, Arc), ethcore::error::Error> +{ + let eth_sync = try!(EthSync::new(sync_cfg, client, net_cfg).map_err(|e| ethcore::error::Error::Util(e))); + Ok((eth_sync.clone() as Arc, eth_sync.clone() as Arc, eth_sync.clone() as Arc)) +} diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 16ba2e8cb..5670d7c94 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -18,7 +18,7 @@ use std::collections::BTreeMap; use std::str::FromStr; use std::sync::Arc; -use ethsync::{EthSync, ManageNetwork}; +use ethsync::{ManageNetwork, SyncProvider}; use ethcore::miner::{Miner, ExternalMiner}; use ethcore::client::Client; use util::RotatingLogger; @@ -76,7 +76,8 @@ pub struct Dependencies { pub signer_port: Option, pub signer_queue: Arc, pub client: Arc, - pub sync: Arc, + pub sync: Arc, + pub net: Arc, pub secret_store: Arc, pub miner: Arc, pub external_miner: Arc, diff --git a/parity/sync/main.rs b/parity/sync/main.rs new file mode 100644 index 000000000..162f6cec1 --- /dev/null +++ b/parity/sync/main.rs @@ -0,0 +1,136 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Parity sync service + +extern crate ethcore_ipc_nano as nanoipc; +extern crate ethcore_ipc_hypervisor as hypervisor; +extern crate ethcore_ipc as ipc; +extern crate ctrlc; +#[macro_use] extern crate log; +extern crate ethsync; +extern crate rustc_serialize; +extern crate docopt; +extern crate ethcore; +extern crate ethcore_util as util; + +use std::sync::Arc; +use hypervisor::{HypervisorServiceClient, SYNC_MODULE_ID, HYPERVISOR_IPC_URL}; +use ctrlc::CtrlC; +use std::sync::atomic::{AtomicBool, Ordering}; +use docopt::Docopt; +use ethcore::client::{RemoteClient, ChainNotify}; +use ethsync::{SyncProvider, SyncConfig, EthSync, ManageNetwork, NetworkConfiguration}; +use std::thread; +use util::numbers::{U256, H256}; +use std::str::FromStr; +use nanoipc::IpcInterface; +use util::sha3::Hashable; + +const USAGE: &'static str = " +Ethcore sync service +Usage: + sync [options] + +Options: + --public-address IP Public address. + --boot-nodes LIST List of boot nodes. + --reserved-nodes LIST List of reserved peers, + --secret HEX Use node key hash + --udp-port UDP port +"; + +#[derive(Debug, RustcDecodable)] +struct Args { + arg_network_id: String, + arg_listen_address: String, + arg_nat_enabled: bool, + arg_discovery_enabled: bool, + arg_ideal_peers: u32, + arg_config_path: String, + arg_client_url: String, + arg_allow_non_reserved: bool, + flag_public_address: Option, + flag_secret: Option, + flag_boot_nodes: Vec, + flag_reserved_nodes: Vec, + flag_udp_port: Option, +} + +impl Args { + pub fn into_config(self) -> (SyncConfig, NetworkConfiguration, String) { + let mut sync_config = SyncConfig::default(); + sync_config.network_id = U256::from_str(&self.arg_network_id).unwrap(); + + let network_config = NetworkConfiguration { + udp_port: self.flag_udp_port, + nat_enabled: self.arg_nat_enabled, + boot_nodes: self.flag_boot_nodes, + listen_address: Some(self.arg_listen_address), + public_address: self.flag_public_address, + use_secret: self.flag_secret.as_ref().map(|s| H256::from_str(s).unwrap_or_else(|_| s.sha3())), + discovery_enabled: self.arg_discovery_enabled, + ideal_peers: self.arg_ideal_peers, + config_path: Some(self.arg_config_path), + reserved_nodes: self.flag_reserved_nodes, + allow_non_reserved: self.arg_allow_non_reserved, + }; + + (sync_config, network_config, self.arg_client_url) + } +} + +fn run_service(addr: &str, stop_guard: Arc, service: Arc) where T: IpcInterface { + let socket_url = addr.to_owned(); + std::thread::spawn(move || { + let mut worker = nanoipc::Worker::::new(&service); + worker.add_reqrep(&socket_url).unwrap(); + + while !stop_guard.load(Ordering::Relaxed) { + worker.poll(); + } + }); +} + +fn main() { + let args: Args = Docopt::new(USAGE) + .and_then(|d| d.decode()) + .unwrap_or_else(|e| e.exit()); + let (sync_config, network_config, client_url) = args.into_config(); + let remote_client = nanoipc::init_client::>(&client_url).unwrap(); + + remote_client.handshake().unwrap(); + + let stop = Arc::new(AtomicBool::new(false)); + let sync = EthSync::new(sync_config, remote_client.service().clone(), network_config).unwrap(); + + run_service("ipc:///tmp/parity-sync.ipc", stop.clone(), sync.clone() as Arc); + run_service("ipc:///tmp/parity-manage-net.ipc", stop.clone(), sync.clone() as Arc); + run_service("ipc:///tmp/parity-sync-notify.ipc", stop.clone(), sync.clone() as Arc); + + let hypervisor_client = nanoipc::init_client::>(HYPERVISOR_IPC_URL).unwrap(); + hypervisor_client.handshake().unwrap(); + hypervisor_client.module_ready(SYNC_MODULE_ID); + + let terminate_stop = stop.clone(); + CtrlC::set_handler(move || { + terminate_stop.store(true, Ordering::Relaxed); + }); + + while !stop.load(Ordering::Relaxed) { + thread::park_timeout(std::time::Duration::from_millis(1000)); + } +} diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 14b3e1192..a3e774662 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -48,7 +48,7 @@ use v1::impls::{default_gas_price, dispatch_transaction, error_codes}; use serde; /// Eth rpc implementation. -pub struct EthClient where +pub struct EthClient where C: MiningBlockChainClient, S: SyncProvider, M: MinerService, @@ -63,7 +63,7 @@ pub struct EthClient where allow_pending_receipt_query: bool, } -impl EthClient where +impl EthClient where C: MiningBlockChainClient, S: SyncProvider, M: MinerService, @@ -244,7 +244,7 @@ fn no_author_err() -> Error { } } -impl EthClient where +impl EthClient where C: MiningBlockChainClient + 'static, S: SyncProvider + 'static, M: MinerService + 'static, @@ -263,7 +263,7 @@ static SOLC: &'static str = "solc.exe"; #[cfg(not(windows))] static SOLC: &'static str = "solc"; -impl Eth for EthClient where +impl Eth for EthClient where C: MiningBlockChainClient + 'static, S: SyncProvider + 'static, M: MinerService + 'static, @@ -517,7 +517,7 @@ impl Eth for EthClient where try!(self.active()); match params { Params::None => { - let mut compilers = vec![]; + let mut compilers = vec![]; if Command::new(SOLC).output().is_ok() { compilers.push("solidity".to_owned()) } diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index 20447ac92..0bbfeca6c 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -21,11 +21,11 @@ use ethsync::SyncProvider; use v1::traits::Net; /// Net rpc implementation. -pub struct NetClient where S: SyncProvider { +pub struct NetClient where S: SyncProvider { sync: Weak } -impl NetClient where S: SyncProvider { +impl NetClient where S: SyncProvider { /// Creates new NetClient. pub fn new(sync: &Arc) -> Self { NetClient { @@ -34,7 +34,7 @@ impl NetClient where S: SyncProvider { } } -impl Net for NetClient where S: SyncProvider + 'static { +impl Net for NetClient where S: SyncProvider + 'static { fn version(&self, _: Params) -> Result { Ok(Value::String(format!("{}", take_weak!(self.sync).status().network_id).to_owned())) } diff --git a/sync/src/api.rs b/sync/src/api.rs index db2ce031a..79970a913 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use util::network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId, NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode}; use util::{TimerToken, U256, H256, UtilError, Secret, Populatable}; -use ethcore::client::{Client, ChainNotify}; +use ethcore::client::{BlockChainClient, ChainNotify}; use io::NetSyncIo; use chain::{ChainSync, SyncStatus}; use std::net::{SocketAddr, AddrParseError}; @@ -67,7 +67,7 @@ pub struct EthSync { impl EthSync { /// Creates and register protocol with the network service - pub fn new(config: SyncConfig, chain: Arc, network_config: NetworkConfiguration) -> Result, UtilError> { + pub fn new(config: SyncConfig, chain: Arc, network_config: NetworkConfiguration) -> Result, UtilError> { let chain_sync = ChainSync::new(config, chain.deref()); let service = try!(NetworkService::new(try!(network_config.into_basic()))); let sync = Arc::new(EthSync{ @@ -90,7 +90,7 @@ impl SyncProvider for EthSync { struct SyncProtocolHandler { /// Shared blockchain client. TODO: this should evetually become an IPC endpoint - chain: Arc, + chain: Arc, /// Sync strategy sync: RwLock, } @@ -149,8 +149,8 @@ impl ChainNotify for EthSync { } } -impl IpcConfig for Arc { } -impl IpcConfig for Arc { } +impl IpcConfig for ManageNetwork { } +impl IpcConfig for SyncProvider { } /// Trait for managing network pub trait ManageNetwork : Send + Sync {