use util::*; use sync::*; use spec::Spec; use error::*; use std::env; use client::Client; /// Message type for external and internal events #[derive(Clone)] pub enum SyncMessage { /// New block has been imported into the blockchain NewChainBlock(Bytes), //TODO: use Cow /// A block is ready BlockVerified, } /// TODO [arkpar] Please document me pub type NetSyncMessage = NetworkIoMessage; /// Client service setup. Creates and registers client and network services with the IO subsystem. pub struct ClientService { net_service: NetworkService, client: Arc, sync: Arc, } impl ClientService { /// Start the service in a separate thread. 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(); dir.push(".parity"); dir.push(H64::from(spec.genesis_header().hash()).hex()); let client = try!(Client::new(spec, &dir, net_service.io().channel())); let sync = EthSync::register(&mut net_service, client.clone()); let client_io = Arc::new(ClientIoHandler { client: client.clone() }); try!(net_service.io().register_handler(client_io)); Ok(ClientService { net_service: net_service, client: client, sync: sync, }) } /// TODO [arkpar] Please document me pub fn io(&mut self) -> &mut IoService { self.net_service.io() } /// TODO [arkpar] Please document me pub fn client(&self) -> Arc { self.client.clone() } /// Get shared sync handler pub fn sync(&self) -> Arc { self.sync.clone() } } /// IO interface for the Client handler struct ClientIoHandler { client: Arc } const CLIENT_TICK_TIMER: TimerToken = 0; const CLIENT_TICK_MS: u64 = 5000; impl IoHandler for ClientIoHandler { fn initialize(&self, io: &IoContext) { io.register_timer(CLIENT_TICK_TIMER, CLIENT_TICK_MS).expect("Error registering client timer"); } fn timeout(&self, _io: &IoContext, timer: TimerToken) { if timer == CLIENT_TICK_TIMER { self.client.tick(); } } #[allow(match_ref_pats)] #[allow(single_match)] fn message(&self, io: &IoContext, net_message: &NetSyncMessage) { if let &UserMessage(ref message) = net_message { match message { &SyncMessage::BlockVerified => { self.client.import_verified_blocks(&io.channel()); }, _ => {}, // ignore other messages } } } }