diff --git a/Cargo.lock b/Cargo.lock index 109db6de676..cf965ba42ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,14 +239,6 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "conv" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam" version = "0.3.2" @@ -336,11 +328,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "custom_derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "daemonize" version = "0.2.3" @@ -1802,39 +1789,11 @@ dependencies = [ "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "node-health" -version = "0.1.0" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-reactor 0.1.0", - "parking_lot 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ntp" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num" version = "0.1.42" @@ -2010,7 +1969,6 @@ dependencies = [ "mem 0.1.0", "migration-rocksdb 0.1.0", "node-filter 1.12.0", - "node-health 0.1.0", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "panic_hook 0.1.0", @@ -2156,7 +2114,6 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "multihash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "node-health 0.1.0", "order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common)", "parity-crypto 0.1.0 (git+https://github.com/paritytech/parity-common)", @@ -3650,7 +3607,6 @@ dependencies = [ "checksum cid 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d85ee025368e69063c420cbb2ed9f852cb03a5e69b73be021e65726ce03585b6" "checksum clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f4a2b3bb7ef3c672d7c13d15613211d5a6976b6892c598b0fcb5d40765f19c2" "checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3" -"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" @@ -3661,7 +3617,6 @@ dependencies = [ "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum ct-logs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61cd11fb222fecf889f4531855c614548e92e8bd2eb178e35296885df5ee9a7c" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" -"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" "checksum daemonize 0.2.3 (git+https://github.com/paritytech/daemonize)" = "" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" @@ -3754,7 +3709,6 @@ dependencies = [ "checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum ntp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06b0d2de4a2cd60c3ac85c98a1fc23668bc97bef2b10b706bccd88efb229497d" "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-bigint 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "81b483ea42927c463e191802e7334556b48e7875297564c0e9951bd3a0ae53e3" "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" diff --git a/Cargo.toml b/Cargo.toml index e7dc4393a84..697afeab3ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,6 @@ ethcore-transaction = { path = "ethcore/transaction" } ethereum-types = "0.3" node-filter = { path = "ethcore/node_filter" } ethkey = { path = "ethkey" } -node-health = { path = "node-health" } rlp = { git = "https://github.com/paritytech/parity-common" } rpc-cli = { path = "rpc_cli" } parity-hash-fetch = { path = "hash-fetch" } diff --git a/node-health/Cargo.toml b/node-health/Cargo.toml deleted file mode 100644 index 22432a5f390..00000000000 --- a/node-health/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "node-health" -description = "Node's health status" -version = "0.1.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] - -[dependencies] -futures = "0.1" -futures-cpupool = "0.1" -log = "0.3" -ntp = "0.5.0" -parking_lot = "0.6" -serde = "1.0" -serde_derive = "1.0" -time = "0.1.35" - -parity-reactor = { path = "../util/reactor" } diff --git a/node-health/src/health.rs b/node-health/src/health.rs deleted file mode 100644 index 430061ea2bb..00000000000 --- a/node-health/src/health.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (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 . - -//! Reporting node's health. - -use std::sync::Arc; -use std::time::Duration; -use futures::Future; -use futures::sync::oneshot; -use types::{HealthInfo, HealthStatus, Health}; -use time::{TimeChecker, MAX_DRIFT}; -use parity_reactor::Remote; -use parking_lot::Mutex; -use {SyncStatus}; - -const TIMEOUT: Duration = Duration::from_secs(5); -const PROOF: &str = "Only one closure is invoked."; - -/// A struct enabling you to query for node's health. -#[derive(Debug, Clone)] -pub struct NodeHealth { - sync_status: Arc, - time: TimeChecker, - remote: Remote, -} - -impl NodeHealth { - /// Creates new `NodeHealth`. - pub fn new(sync_status: Arc, time: TimeChecker, remote: Remote) -> Self { - NodeHealth { sync_status, time, remote, } - } - - /// Query latest health report. - pub fn health(&self) -> Box + Send> { - trace!(target: "dapps", "Checking node health."); - // Check timediff - let sync_status = self.sync_status.clone(); - let time = self.time.time_drift(); - let (tx, rx) = oneshot::channel(); - let tx = Arc::new(Mutex::new(Some(tx))); - let tx2 = tx.clone(); - self.remote.spawn_with_timeout( - move |_| time.then(move |result| { - let _ = tx.lock().take().expect(PROOF).send(Ok(result)); - Ok(()) - }), - TIMEOUT, - move || { - let _ = tx2.lock().take().expect(PROOF).send(Err(())); - }, - ); - - Box::new(rx.map_err(|err| { - warn!(target: "dapps", "Health request cancelled: {:?}", err); - }).and_then(move |time| { - // Check peers - let peers = { - let (connected, max) = sync_status.peers(); - let (status, message) = match connected { - 0 => { - (HealthStatus::Bad, "You are not connected to any peers. There is most likely some network issue. Fix connectivity.".into()) - }, - 1 => (HealthStatus::NeedsAttention, "You are connected to only one peer. Your node might not be reliable. Check your network connection.".into()), - _ => (HealthStatus::Ok, "".into()), - }; - HealthInfo { status, message, details: (connected, max) } - }; - - // Check sync - let sync = { - let is_syncing = sync_status.is_major_importing(); - let (status, message) = if is_syncing { - (HealthStatus::NeedsAttention, "Your node is still syncing, the values you see might be outdated. Wait until it's fully synced.".into()) - } else { - (HealthStatus::Ok, "".into()) - }; - HealthInfo { status, message, details: is_syncing } - }; - - // Check time - let time = { - let (status, message, details) = match time { - Ok(Ok(diff)) if diff < MAX_DRIFT && diff > -MAX_DRIFT => { - (HealthStatus::Ok, "".into(), diff) - }, - Ok(Ok(diff)) => { - (HealthStatus::Bad, format!( - "Your clock is not in sync. Detected difference is too big for the protocol to work: {}ms. Synchronize your clock.", - diff, - ), diff) - }, - Ok(Err(err)) => { - (HealthStatus::NeedsAttention, format!( - "Unable to reach time API: {}. Make sure that your clock is synchronized.", - err, - ), 0) - }, - Err(_) => { - (HealthStatus::NeedsAttention, "Time API request timed out. Make sure that the clock is synchronized.".into(), 0) - }, - }; - - HealthInfo { status, message, details, } - }; - - Ok(Health { peers, sync, time}) - })) - } -} diff --git a/node-health/src/lib.rs b/node-health/src/lib.rs deleted file mode 100644 index 13529004a6c..00000000000 --- a/node-health/src/lib.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (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 . - -//! Node Health status reporting. - -#![warn(missing_docs)] - -extern crate futures; -extern crate futures_cpupool; -extern crate ntp; -extern crate time as time_crate; -extern crate parity_reactor; -extern crate parking_lot; - -#[macro_use] -extern crate log; -#[macro_use] -extern crate serde_derive; - -mod health; -mod time; -mod types; - -pub use futures_cpupool::CpuPool; -pub use health::NodeHealth; -pub use types::{Health, HealthInfo, HealthStatus}; -pub use time::{TimeChecker, Error}; - -/// Indicates sync status -pub trait SyncStatus: ::std::fmt::Debug + Send + Sync { - /// Returns true if there is a major sync happening. - fn is_major_importing(&self) -> bool; - - /// Returns number of connected and ideal peers. - fn peers(&self) -> (usize, usize); -} diff --git a/node-health/src/time.rs b/node-health/src/time.rs deleted file mode 100644 index 9dfb3aa87f4..00000000000 --- a/node-health/src/time.rs +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (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 . - -//! Periodically checks node's time drift using [SNTP](https://tools.ietf.org/html/rfc1769). -//! -//! An NTP packet is sent to the server with a local timestamp, the server then completes the packet, yielding the -//! following timestamps: -//! -//! Timestamp Name ID When Generated -//! ------------------------------------------------------------ -//! Originate Timestamp T1 time request sent by client -//! Receive Timestamp T2 time request received at server -//! Transmit Timestamp T3 time reply sent by server -//! Destination Timestamp T4 time reply received at client -//! -//! The drift is defined as: -//! -//! drift = ((T2 - T1) + (T3 - T4)) / 2. -//! - -use std::io; -use std::{fmt, mem, time}; -use std::collections::VecDeque; -use std::sync::atomic::{self, AtomicUsize}; -use std::sync::Arc; - -use futures::{self, Future}; -use futures::future::{self, IntoFuture}; -use futures_cpupool::{CpuPool, CpuFuture}; -use ntp; -use parking_lot::RwLock; -use time_crate::{Duration, Timespec}; - -/// Time checker error. -#[derive(Debug, Clone, PartialEq)] -pub enum Error { - /// No servers are currently available for a query. - NoServersAvailable, - /// There was an error when trying to reach the NTP server. - Ntp(String), - /// IO error when reading NTP response. - Io(String), -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - - match *self { - NoServersAvailable => write!(fmt, "No NTP servers available"), - Ntp(ref err) => write!(fmt, "NTP error: {}", err), - Io(ref err) => write!(fmt, "Connection Error: {}", err), - } - } -} - -impl From for Error { - fn from(err: io::Error) -> Self { Error::Io(format!("{}", err)) } -} - -impl From for Error { - fn from(err: ntp::errors::Error) -> Self { Error::Ntp(format!("{}", err)) } -} - -/// NTP time drift checker. -pub trait Ntp { - /// Returned Future. - type Future: IntoFuture; - - /// Returns the current time drift. - fn drift(&self) -> Self::Future; -} - -const SERVER_MAX_POLL_INTERVAL_SECS: u64 = 60; -#[derive(Debug)] -struct Server { - pub address: String, - next_call: RwLock, - failures: AtomicUsize, -} - -impl Server { - pub fn is_available(&self) -> bool { - *self.next_call.read() < time::Instant::now() - } - - pub fn report_success(&self) { - self.failures.store(0, atomic::Ordering::SeqCst); - self.update_next_call(1) - } - - pub fn report_failure(&self) { - let errors = self.failures.fetch_add(1, atomic::Ordering::SeqCst); - self.update_next_call(1 << errors) - } - - fn update_next_call(&self, delay: usize) { - *self.next_call.write() = time::Instant::now() + time::Duration::from_secs(delay as u64 * SERVER_MAX_POLL_INTERVAL_SECS); - } -} - -impl> From for Server { - fn from(t: T) -> Self { - Server { - address: t.as_ref().to_owned(), - next_call: RwLock::new(time::Instant::now()), - failures: Default::default(), - } - } -} - -/// NTP client using the SNTP algorithm for calculating drift. -#[derive(Clone)] -pub struct SimpleNtp { - addresses: Vec>, - pool: CpuPool, -} - -impl fmt::Debug for SimpleNtp { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f - .debug_struct("SimpleNtp") - .field("addresses", &self.addresses) - .finish() - } -} - -impl SimpleNtp { - fn new>(addresses: &[T], pool: CpuPool) -> SimpleNtp { - SimpleNtp { - addresses: addresses.iter().map(Server::from).map(Arc::new).collect(), - pool: pool, - } - } -} - -impl Ntp for SimpleNtp { - type Future = future::Either< - CpuFuture, - future::FutureResult, - >; - - fn drift(&self) -> Self::Future { - use self::future::Either::{A, B}; - - let server = self.addresses.iter().find(|server| server.is_available()); - server.map(|server| { - let server = server.clone(); - A(self.pool.spawn_fn(move || { - debug!(target: "dapps", "Fetching time from {}.", server.address); - - match ntp::request(&server.address) { - Ok(packet) => { - let dest_time = ::time_crate::now_utc().to_timespec(); - let orig_time = Timespec::from(packet.orig_time); - let recv_time = Timespec::from(packet.recv_time); - let transmit_time = Timespec::from(packet.transmit_time); - - let drift = ((recv_time - orig_time) + (transmit_time - dest_time)) / 2; - - server.report_success(); - Ok(drift) - }, - Err(err) => { - server.report_failure(); - Err(err.into()) - }, - } - })) - }).unwrap_or_else(|| B(future::err(Error::NoServersAvailable))) - } -} - -// NOTE In a positive scenario first results will be seen after: -// MAX_RESULTS * UPDATE_TIMEOUT_INCOMPLETE_SECS seconds. -const MAX_RESULTS: usize = 4; -const UPDATE_TIMEOUT_OK_SECS: u64 = 6 * 60 * 60; -const UPDATE_TIMEOUT_WARN_SECS: u64 = 15 * 60; -const UPDATE_TIMEOUT_ERR_SECS: u64 = 60; -const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10; - -/// Maximal valid time drift. -pub const MAX_DRIFT: i64 = 10_000; - -type BoxFuture = Box + Send>; - -#[derive(Debug, Clone)] -/// A time checker. -pub struct TimeChecker { - ntp: N, - last_result: Arc>)>>, -} - -impl TimeChecker { - /// Creates new time checker given the NTP server address. - pub fn new>(ntp_addresses: &[T], pool: CpuPool) -> Self { - let last_result = Arc::new(RwLock::new( - // Assume everything is ok at the very beginning. - (time::Instant::now(), vec![Ok(0)].into()) - )); - - let ntp = SimpleNtp::new(ntp_addresses, pool); - - TimeChecker { - ntp, - last_result, - } - } -} - -impl TimeChecker where ::Future: Send + 'static { - /// Updates the time - pub fn update(&self) -> BoxFuture { - trace!(target: "dapps", "Updating time from NTP."); - let last_result = self.last_result.clone(); - Box::new(self.ntp.drift().into_future().then(move |res| { - let res = res.map(|d| d.num_milliseconds()); - - if let Err(Error::NoServersAvailable) = res { - debug!(target: "dapps", "No NTP servers available. Selecting an older result."); - return select_result(last_result.read().1.iter()); - } - - // Update the results. - let mut results = mem::replace(&mut last_result.write().1, VecDeque::new()); - let has_all_results = results.len() >= MAX_RESULTS; - let valid_till = time::Instant::now() + time::Duration::from_secs( - match res { - Ok(time) if has_all_results && time < MAX_DRIFT => UPDATE_TIMEOUT_OK_SECS, - Ok(_) if has_all_results => UPDATE_TIMEOUT_WARN_SECS, - Err(_) if has_all_results => UPDATE_TIMEOUT_ERR_SECS, - _ => UPDATE_TIMEOUT_INCOMPLETE_SECS, - } - ); - - trace!(target: "dapps", "New time drift received: {:?}", res); - // Push the result. - results.push_back(res); - while results.len() > MAX_RESULTS { - results.pop_front(); - } - - // Select a response and update last result. - let res = select_result(results.iter()); - *last_result.write() = (valid_till, results); - res - })) - } - - /// Returns a current time drift or error if last request to NTP server failed. - pub fn time_drift(&self) -> BoxFuture { - // return cached result - { - let res = self.last_result.read(); - if res.0 > time::Instant::now() { - return Box::new(futures::done(select_result(res.1.iter()))); - } - } - // or update and return result - self.update() - } -} - -fn select_result<'a, T: Iterator>>(results: T) -> Result { - let mut min = None; - for res in results { - min = Some(match (min.take(), res) { - (Some(Ok(min)), &Ok(ref new)) => Ok(::std::cmp::min(min, *new)), - (Some(Ok(old)), &Err(_)) => Ok(old), - (_, ref new) => (*new).clone(), - }) - } - - min.unwrap_or_else(|| Err(Error::Ntp("NTP server unavailable.".into()))) -} - -#[cfg(test)] -mod tests { - use std::sync::Arc; - use std::cell::{Cell, RefCell}; - use std::time::Instant; - use time::Duration; - use futures::{future, Future}; - use super::{Ntp, TimeChecker, Error}; - use parking_lot::RwLock; - - #[derive(Clone)] - struct FakeNtp(RefCell>, Cell); - impl FakeNtp { - fn new() -> FakeNtp { - FakeNtp( - RefCell::new(vec![Duration::milliseconds(150)]), - Cell::new(0)) - } - } - - impl Ntp for FakeNtp { - type Future = future::FutureResult; - - fn drift(&self) -> Self::Future { - self.1.set(self.1.get() + 1); - future::ok(self.0.borrow_mut().pop().expect("Unexpected call to drift().")) - } - } - - fn time_checker() -> TimeChecker { - let last_result = Arc::new(RwLock::new( - (Instant::now(), vec![Err(Error::Ntp("NTP server unavailable".into()))].into()) - )); - - TimeChecker { - ntp: FakeNtp::new(), - last_result: last_result, - } - } - - #[test] - fn should_fetch_time_on_start() { - // given - let time = time_checker(); - - // when - let diff = time.time_drift().wait().unwrap(); - - // then - assert_eq!(diff, 150); - assert_eq!(time.ntp.1.get(), 1); - } - - #[test] - fn should_not_fetch_twice_if_timeout_has_not_passed() { - // given - let time = time_checker(); - - // when - let diff1 = time.time_drift().wait().unwrap(); - let diff2 = time.time_drift().wait().unwrap(); - - // then - assert_eq!(diff1, 150); - assert_eq!(diff2, 150); - assert_eq!(time.ntp.1.get(), 1); - } -} diff --git a/node-health/src/types.rs b/node-health/src/types.rs deleted file mode 100644 index 76fd3682f96..00000000000 --- a/node-health/src/types.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (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 . - -//! Base health types. - -/// Health API endpoint status. -#[derive(Debug, PartialEq, Serialize)] -pub enum HealthStatus { - /// Everything's OK. - #[serde(rename = "ok")] - Ok, - /// Node health need attention - /// (the issue is not critical, but may need investigation) - #[serde(rename = "needsAttention")] - NeedsAttention, - /// There is something bad detected with the node. - #[serde(rename = "bad")] - Bad, -} - -/// Represents a single check in node health. -/// Cointains the status of that check and apropriate message and details. -#[derive(Debug, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct HealthInfo { - /// Check status. - pub status: HealthStatus, - /// Human-readable message. - pub message: String, - /// Technical details of the check. - pub details: T, -} - -/// Node Health status. -#[derive(Debug, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct Health { - /// Status of peers. - pub peers: HealthInfo<(usize, usize)>, - /// Sync status. - pub sync: HealthInfo, - /// Time diff info. - pub time: HealthInfo, -} diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index d67da3db7b4..8c1721160a3 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -790,10 +790,6 @@ usage! { "--no-config", "Don't load a configuration file.", - ARG arg_ntp_servers: (String) = "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123", or |c: &Config| c.misc.as_ref()?.ntp_servers.clone().map(|vec| vec.join(",")), - "--ntp-servers=[HOSTS]", - "Comma separated list of NTP servers to provide current time (host:port). Used to verify node health. Parity uses pool.ntp.org NTP servers; consider joining the pool: http://www.pool.ntp.org/join.html", - ARG arg_logging: (Option) = None, or |c: &Config| c.misc.as_ref()?.logging.clone(), "-l, --logging=[LOGGING]", "Specify the general logging level (error, warn, info, debug or trace). It can also be set for a specific module, example: '-l sync=debug,rpc=trace'", @@ -1073,6 +1069,10 @@ usage! { ARG arg_dapps_path: (Option) = None, or |c: &Config| c.dapps.as_ref()?._legacy_path.clone(), "--dapps-path=[PATH]", "Specify directory where dapps should be installed.", + + ARG arg_ntp_servers: (Option) = None, or |_| None, + "--ntp-servers=[HOSTS]", + "Does nothing; checking if clock is sync with NTP servers is now done on the UI.", } } @@ -1345,7 +1345,6 @@ struct Snapshots { #[derive(Default, Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] struct Misc { - ntp_servers: Option>, logging: Option, log_file: Option, color: Option, @@ -1812,7 +1811,7 @@ mod tests { flag_can_restart: false, // -- Miscellaneous Options - arg_ntp_servers: "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123".into(), + arg_ntp_servers: None, flag_version: false, arg_logging: Some("own_tx=trace".into()), arg_log_file: Some("/var/log/parity.log".into()), @@ -2017,7 +2016,6 @@ mod tests { disable_periodic: Some(true), }), misc: Some(Misc { - ntp_servers: Some(vec!["0.parity.pool.ntp.org:123".into()]), logging: Some("own_tx=trace".into()), log_file: Some("/var/log/parity.log".into()), color: Some(true), diff --git a/parity/cli/tests/config.toml b/parity/cli/tests/config.toml index 9fffe4cb051..5f9e655d51c 100644 --- a/parity/cli/tests/config.toml +++ b/parity/cli/tests/config.toml @@ -74,7 +74,6 @@ scale_verifiers = false disable_periodic = true [misc] -ntp_servers = ["0.parity.pool.ntp.org:123"] logging = "own_tx=trace" log_file = "/var/log/parity.log" color = true diff --git a/parity/configuration.rs b/parity/configuration.rs index f904c169c0f..52bcc40b218 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -348,7 +348,6 @@ impl Configuration { miner_options: self.miner_options()?, gas_price_percentile: self.args.arg_gas_price_percentile, poll_lifetime: self.args.arg_poll_lifetime, - ntp_servers: self.ntp_servers(), ws_conf: ws_conf, http_conf: http_conf, ipc_conf: ipc_conf, @@ -574,10 +573,6 @@ impl Configuration { }) } - fn ntp_servers(&self) -> Vec { - self.args.arg_ntp_servers.split(",").map(str::to_owned).collect() - } - fn secretstore_config(&self) -> Result { Ok(SecretStoreConfiguration { enabled: self.secretstore_enabled(), @@ -1368,12 +1363,6 @@ mod tests { miner_options: Default::default(), gas_price_percentile: 50, poll_lifetime: 60, - ntp_servers: vec![ - "0.parity.pool.ntp.org:123".into(), - "1.parity.pool.ntp.org:123".into(), - "2.parity.pool.ntp.org:123".into(), - "3.parity.pool.ntp.org:123".into(), - ], ws_conf: Default::default(), http_conf: Default::default(), ipc_conf: Default::default(), diff --git a/parity/deprecated.rs b/parity/deprecated.rs index 514e7d5d92d..91a872e2202 100644 --- a/parity/deprecated.rs +++ b/parity/deprecated.rs @@ -225,6 +225,10 @@ pub fn find_deprecated(args: &Args) -> Vec { result.push(Deprecated::Removed("--dapps-path")); } + if args.arg_ntp_servers.is_some() { + result.push(Deprecated::Removed("--ntp-servers")); + } + result } @@ -256,6 +260,7 @@ mod tests { args.arg_dapps_pass = Some(Default::default()); args.flag_dapps_apis_all = true; args.flag_fast_and_loose = true; + args.arg_ntp_servers = Some(Default::default()); args }), vec![ Deprecated::DoesNothing("--warp"), @@ -276,6 +281,7 @@ mod tests { Deprecated::Removed("--dapps-pass"), Deprecated::Replaced("--dapps-apis-all", "--jsonrpc-apis"), Deprecated::Removed("--fast-and-loose"), + Deprecated::Removed("--ntp-servers"), ]); } } diff --git a/parity/lib.rs b/parity/lib.rs index b1b385a1a31..93edd74982b 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -57,7 +57,6 @@ extern crate ethcore_transaction as transaction; extern crate ethereum_types; extern crate ethkey; extern crate kvdb; -extern crate node_health; extern crate panic_hook; extern crate parity_hash_fetch as hash_fetch; extern crate parity_ipfs_api; diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index cf9f6d2dd59..7ecbaee5f5f 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -34,7 +34,6 @@ use jsonrpc_core::{self as core, MetaIoHandler}; use light::client::LightChainClient; use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache}; use miner::external::ExternalMiner; -use node_health::NodeHealth; use parity_reactor; use parity_rpc::dispatch::{FullDispatcher, LightDispatcher}; use parity_rpc::informant::{ActivityNotifier, ClientNotifier}; @@ -224,7 +223,6 @@ pub struct FullDependencies { pub settings: Arc, pub net_service: Arc, pub updater: Arc, - pub health: NodeHealth, pub geth_compatibility: bool, pub ws_address: Option, pub fetch: FetchClient, @@ -329,7 +327,6 @@ impl FullDependencies { self.sync.clone(), self.updater.clone(), self.net_service.clone(), - self.health.clone(), self.secret_store.clone(), self.logger.clone(), self.settings.clone(), @@ -430,7 +427,6 @@ pub struct LightDependencies { pub secret_store: Arc, pub logger: Arc, pub settings: Arc, - pub health: NodeHealth, pub on_demand: Arc<::light::on_demand::OnDemand>, pub cache: Arc>, pub transaction_queue: Arc>, @@ -544,7 +540,6 @@ impl LightDependencies { self.secret_store.clone(), self.logger.clone(), self.settings.clone(), - self.health.clone(), signer, self.ws_address.clone(), self.gas_price_percentile, diff --git a/parity/run.rs b/parity/run.rs index fb52d86798e..8d738b493bf 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -15,7 +15,6 @@ // along with Parity. If not, see . use std::any::Any; -use std::fmt; use std::sync::{Arc, Weak}; use std::time::{Duration, Instant}; use std::thread; @@ -42,7 +41,6 @@ use journaldb::Algorithm; use light::Cache as LightDataCache; use miner::external::ExternalMiner; use node_filter::NodeFilter; -use node_health; use parity_reactor::EventLoop; use parity_rpc::{Origin, Metadata, NetworkSettings, informant, is_major_importing}; use updater::{UpdatePolicy, Updater}; @@ -95,7 +93,6 @@ pub struct RunCmd { pub miner_options: MinerOptions, pub gas_price_percentile: usize, pub poll_lifetime: u32, - pub ntp_servers: Vec, pub ws_conf: rpc::WsConfiguration, pub http_conf: rpc::HttpConfiguration, pub ipc_conf: rpc::IpcConfiguration, @@ -287,28 +284,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result); - impl fmt::Debug for LightSyncStatus { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Light Sync Status") - } - } - impl node_health::SyncStatus for LightSyncStatus { - fn is_major_importing(&self) -> bool { self.0.is_major_importing() } - fn peers(&self) -> (usize, usize) { - let peers = sync::LightSyncProvider::peer_numbers(&*self.0); - (peers.connected, peers.max) - } - } - - let sync_status = Arc::new(LightSyncStatus(light_sync.clone())); - node_health::NodeHealth::new( - sync_status.clone(), - node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()), - event_loop.remote(), - ) - }; // start RPCs let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies { @@ -316,7 +291,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: let secret_store = account_provider.clone(); let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config)); - // the dapps server - let node_health = { - let (sync, client) = (sync_provider.clone(), client.clone()); - - struct SyncStatus(Arc, Arc, sync::NetworkConfiguration); - impl fmt::Debug for SyncStatus { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Dapps Sync Status") - } - } - impl node_health::SyncStatus for SyncStatus { - fn is_major_importing(&self) -> bool { - is_major_importing(Some(self.0.status().state), self.1.queue_info()) - } - fn peers(&self) -> (usize, usize) { - let status = self.0.status(); - (status.num_peers, status.current_max_peers(self.2.min_peers, self.2.max_peers) as usize) - } - } - - let sync_status = Arc::new(SyncStatus(sync, client, net_conf)); - node_health::NodeHealth::new( - sync_status.clone(), - node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()), - event_loop.remote(), - ) - }; - let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies { signer_service: signer_service, snapshot: snapshot_service.clone(), client: client.clone(), sync: sync_provider.clone(), - health: node_health, net: manage_network.clone(), secret_store: secret_store, miner: miner.clone(), diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index d551d90c530..7e25871a350 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -54,7 +54,6 @@ ethkey = { path = "../ethkey" } ethstore = { path = "../ethstore" } fetch = { path = "../util/fetch" } keccak-hash = { git = "https://github.com/paritytech/parity-common" } -node-health = { path = "../node-health" } parity-reactor = { path = "../util/reactor" } parity-updater = { path = "../updater" } parity-version = { path = "../util/version" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index bef7d9effb4..e748b840c0f 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -60,7 +60,6 @@ extern crate ethkey; extern crate ethstore; extern crate fetch; extern crate keccak_hash as hash; -extern crate node_health; extern crate parity_reactor; extern crate parity_updater as updater; extern crate parity_version as version; diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index f9ec03cd378..e7dcbe9e9ab 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -26,7 +26,6 @@ use ethstore::random_phrase; use sync::LightSyncProvider; use ethcore::account_provider::AccountProvider; use ethcore_logger::RotatingLogger; -use node_health::{NodeHealth, Health}; use ethcore::ids::BlockId; use light::client::LightChainClient; @@ -56,7 +55,6 @@ pub struct ParityClient { accounts: Arc, logger: Arc, settings: Arc, - health: NodeHealth, signer: Option>, ws_address: Option, eip86_transition: u64, @@ -71,7 +69,6 @@ impl ParityClient { accounts: Arc, logger: Arc, settings: Arc, - health: NodeHealth, signer: Option>, ws_address: Option, gas_price_percentile: usize, @@ -81,7 +78,6 @@ impl ParityClient { accounts, logger, settings, - health, signer, ws_address, eip86_transition: client.eip86_transition(), @@ -432,9 +428,4 @@ impl Parity for ParityClient { fn call(&self, _meta: Self::Metadata, _requests: Vec, _block: Trailing) -> Result> { Err(errors::light_unimplemented(None)) } - - fn node_health(&self) -> BoxFuture { - Box::new(self.health.health() - .map_err(|err| errors::internal("Health API failure.", err))) - } } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 93560836f9c..c4c2ac9dba8 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -32,10 +32,9 @@ use ethcore::ids::BlockId; use ethcore::miner::{self, MinerService}; use ethcore::state::StateInfo; use ethcore_logger::RotatingLogger; -use node_health::{NodeHealth, Health}; use updater::{Service as UpdateService}; use jsonrpc_core::{BoxFuture, Result}; -use jsonrpc_core::futures::{future, Future}; +use jsonrpc_core::futures::future; use jsonrpc_macros::Trailing; use v1::helpers::{self, errors, fake_sign, ipfs, SigningQueue, SignerService, NetworkSettings}; use v1::metadata::Metadata; @@ -58,7 +57,6 @@ pub struct ParityClient { updater: Arc, sync: Arc, net: Arc, - health: NodeHealth, accounts: Arc, logger: Arc, settings: Arc, @@ -77,7 +75,6 @@ impl ParityClient where sync: Arc, updater: Arc, net: Arc, - health: NodeHealth, accounts: Arc, logger: Arc, settings: Arc, @@ -91,7 +88,6 @@ impl ParityClient where sync, updater, net, - health, accounts, logger, settings, @@ -466,9 +462,4 @@ impl Parity for ParityClient where .map(|res| res.into_iter().map(|res| res.output.into()).collect()) .map_err(errors::call) } - - fn node_health(&self) -> BoxFuture { - Box::new(self.health.health() - .map_err(|err| errors::internal("Health API failure.", err))) - } } diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index ca241140640..300badd742d 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -21,8 +21,6 @@ use ethcore_logger::RotatingLogger; use ethereum_types::{Address, U256, H256}; use ethstore::ethkey::{Generator, Random}; use miner::pool::local_transactions::Status as LocalTransactionStatus; -use node_health::{self, NodeHealth}; -use parity_reactor; use sync::ManageNetwork; use jsonrpc_core::IoHandler; @@ -40,7 +38,6 @@ pub struct Dependencies { pub client: Arc, pub sync: Arc, pub updater: Arc, - pub health: NodeHealth, pub logger: Arc, pub settings: Arc, pub network: Arc, @@ -57,11 +54,6 @@ impl Dependencies { network_id: 3, num_peers: 120, })), - health: NodeHealth::new( - Arc::new(FakeSync), - node_health::TimeChecker::new::(&[], node_health::CpuPool::new(1)), - parity_reactor::Remote::new_sync(), - ), updater: Arc::new(TestUpdater::default()), logger: Arc::new(RotatingLogger::new("rpc=trace".to_owned())), settings: Arc::new(NetworkSettings { @@ -85,7 +77,6 @@ impl Dependencies { self.sync.clone(), self.updater.clone(), self.network.clone(), - self.health.clone(), self.accounts.clone(), self.logger.clone(), self.settings.clone(), @@ -107,13 +98,6 @@ impl Dependencies { } } -#[derive(Debug)] -struct FakeSync; -impl node_health::SyncStatus for FakeSync { - fn is_major_importing(&self) -> bool { false } - fn peers(&self) -> (usize, usize) { (4, 25) } -} - #[test] fn rpc_parity_accounts_info() { let deps = Dependencies::new(); @@ -554,14 +538,3 @@ fn rpc_parity_call() { assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } - -#[test] -fn rpc_parity_node_health() { - let deps = Dependencies::new(); - let io = deps.default_client(); - - let request = r#"{"jsonrpc": "2.0", "method": "parity_nodeHealth", "params":[], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":{"peers":{"details":[4,25],"message":"","status":"ok"},"sync":{"details":false,"message":"","status":"ok"},"time":{"details":0,"message":"","status":"ok"}},"id":1}"#; - - assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); -} diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 2f2eef90741..1cc6aca9629 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -21,7 +21,6 @@ use std::collections::BTreeMap; use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_macros::Trailing; -use node_health::Health; use v1::types::{ H160, H256, H512, U256, U64, Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, @@ -219,9 +218,5 @@ build_rpc_trait! { /// Call contract, returning the output data. #[rpc(meta, name = "parity_call")] fn call(&self, Self::Metadata, Vec, Trailing) -> Result>; - - /// Returns node's health report. - #[rpc(name = "parity_nodeHealth")] - fn node_health(&self) -> BoxFuture; } }