Remove node-health (#9119)
* Remove node-health * Remove ntp_servers * Add --ntp-servers as legacy instead of removing it * Add --ntp-servers to deprecated args * Remove unused stuff * Remove _legacy_ntp_servers
This commit is contained in:
		
							parent
							
								
									dbccc700f1
								
							
						
					
					
						commit
						3c27587d83
					
				
							
								
								
									
										46
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										46
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -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)" = "<none>"
 | 
			
		||||
"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)" = "<none>"
 | 
			
		||||
"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"
 | 
			
		||||
 | 
			
		||||
@ -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" }
 | 
			
		||||
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "node-health"
 | 
			
		||||
description = "Node's health status"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
license = "GPL-3.0"
 | 
			
		||||
authors = ["Parity Technologies <admin@parity.io>"]
 | 
			
		||||
 | 
			
		||||
[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" }
 | 
			
		||||
@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
//! 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<SyncStatus>,
 | 
			
		||||
	time: TimeChecker,
 | 
			
		||||
	remote: Remote,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NodeHealth {
 | 
			
		||||
	/// Creates new `NodeHealth`.
 | 
			
		||||
	pub fn new(sync_status: Arc<SyncStatus>, time: TimeChecker, remote: Remote) -> Self {
 | 
			
		||||
		NodeHealth { sync_status, time, remote, }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Query latest health report.
 | 
			
		||||
	pub fn health(&self) -> Box<Future<Item = Health, Error = ()> + 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})
 | 
			
		||||
		}))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
//! 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);
 | 
			
		||||
}
 | 
			
		||||
@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
//! 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<io::Error> for Error {
 | 
			
		||||
	fn from(err: io::Error) -> Self { Error::Io(format!("{}", err)) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<ntp::errors::Error> 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<Item=Duration, Error=Error>;
 | 
			
		||||
 | 
			
		||||
	/// 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<time::Instant>,
 | 
			
		||||
	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<T: AsRef<str>> From<T> 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<Arc<Server>>,
 | 
			
		||||
	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<T: AsRef<str>>(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<Duration, Error>,
 | 
			
		||||
		future::FutureResult<Duration, Error>,
 | 
			
		||||
	>;
 | 
			
		||||
 | 
			
		||||
	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<A, B> = Box<Future<Item = A, Error = B> + Send>;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
/// A time checker.
 | 
			
		||||
pub struct TimeChecker<N: Ntp = SimpleNtp> {
 | 
			
		||||
	ntp: N,
 | 
			
		||||
	last_result: Arc<RwLock<(time::Instant, VecDeque<Result<i64, Error>>)>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TimeChecker<SimpleNtp> {
 | 
			
		||||
	/// Creates new time checker given the NTP server address.
 | 
			
		||||
	pub fn new<T: AsRef<str>>(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<N: Ntp> TimeChecker<N> where <N::Future as IntoFuture>::Future: Send + 'static {
 | 
			
		||||
	/// Updates the time
 | 
			
		||||
	pub fn update(&self) -> BoxFuture<i64, Error> {
 | 
			
		||||
		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<i64, Error> {
 | 
			
		||||
		// 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<Item=&'a Result<i64, Error>>>(results: T) -> Result<i64, Error> {
 | 
			
		||||
	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<Vec<Duration>>, Cell<u64>);
 | 
			
		||||
	impl FakeNtp {
 | 
			
		||||
		fn new() -> FakeNtp {
 | 
			
		||||
			FakeNtp(
 | 
			
		||||
				RefCell::new(vec![Duration::milliseconds(150)]),
 | 
			
		||||
				Cell::new(0))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	impl Ntp for FakeNtp {
 | 
			
		||||
		type Future = future::FutureResult<Duration, Error>;
 | 
			
		||||
 | 
			
		||||
		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<FakeNtp> {
 | 
			
		||||
		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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
//! 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<T> {
 | 
			
		||||
	/// 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<bool>,
 | 
			
		||||
	/// Time diff info.
 | 
			
		||||
	pub time: HealthInfo<i64>,
 | 
			
		||||
}
 | 
			
		||||
@ -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<String>) = 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<String>) = 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<String>) = 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<Vec<String>>,
 | 
			
		||||
	logging: Option<String>,
 | 
			
		||||
	log_file: Option<String>,
 | 
			
		||||
	color: Option<bool>,
 | 
			
		||||
@ -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),
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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<String> {
 | 
			
		||||
		self.args.arg_ntp_servers.split(",").map(str::to_owned).collect()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
 | 
			
		||||
		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(),
 | 
			
		||||
 | 
			
		||||
@ -225,6 +225,10 @@ pub fn find_deprecated(args: &Args) -> Vec<Deprecated> {
 | 
			
		||||
		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"),
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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<NetworkSettings>,
 | 
			
		||||
	pub net_service: Arc<ManageNetwork>,
 | 
			
		||||
	pub updater: Arc<Updater>,
 | 
			
		||||
	pub health: NodeHealth,
 | 
			
		||||
	pub geth_compatibility: bool,
 | 
			
		||||
	pub ws_address: Option<Host>,
 | 
			
		||||
	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<T> {
 | 
			
		||||
	pub secret_store: Arc<AccountProvider>,
 | 
			
		||||
	pub logger: Arc<RotatingLogger>,
 | 
			
		||||
	pub settings: Arc<NetworkSettings>,
 | 
			
		||||
	pub health: NodeHealth,
 | 
			
		||||
	pub on_demand: Arc<::light::on_demand::OnDemand>,
 | 
			
		||||
	pub cache: Arc<Mutex<LightDataCache>>,
 | 
			
		||||
	pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
 | 
			
		||||
@ -544,7 +540,6 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
 | 
			
		||||
						self.secret_store.clone(),
 | 
			
		||||
						self.logger.clone(),
 | 
			
		||||
						self.settings.clone(),
 | 
			
		||||
						self.health.clone(),
 | 
			
		||||
						signer,
 | 
			
		||||
						self.ws_address.clone(),
 | 
			
		||||
						self.gas_price_percentile,
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,6 @@
 | 
			
		||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
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<String>,
 | 
			
		||||
	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<RotatingLogger>) -> Result<Runnin
 | 
			
		||||
 | 
			
		||||
	// the dapps server
 | 
			
		||||
	let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
 | 
			
		||||
	let node_health = {
 | 
			
		||||
		struct LightSyncStatus(Arc<LightSync>);
 | 
			
		||||
		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<RotatingLogger>) -> Result<Runnin
 | 
			
		||||
		client: client.clone(),
 | 
			
		||||
		sync: light_sync.clone(),
 | 
			
		||||
		net: light_sync.clone(),
 | 
			
		||||
		health: node_health,
 | 
			
		||||
		secret_store: account_provider,
 | 
			
		||||
		logger: logger,
 | 
			
		||||
		settings: Arc::new(cmd.net_settings),
 | 
			
		||||
@ -718,40 +692,11 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, 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<sync::SyncProvider>, Arc<Client>, 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(),
 | 
			
		||||
 | 
			
		||||
@ -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" }
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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<AccountProvider>,
 | 
			
		||||
	logger: Arc<RotatingLogger>,
 | 
			
		||||
	settings: Arc<NetworkSettings>,
 | 
			
		||||
	health: NodeHealth,
 | 
			
		||||
	signer: Option<Arc<SignerService>>,
 | 
			
		||||
	ws_address: Option<Host>,
 | 
			
		||||
	eip86_transition: u64,
 | 
			
		||||
@ -71,7 +69,6 @@ impl ParityClient {
 | 
			
		||||
		accounts: Arc<AccountProvider>,
 | 
			
		||||
		logger: Arc<RotatingLogger>,
 | 
			
		||||
		settings: Arc<NetworkSettings>,
 | 
			
		||||
		health: NodeHealth,
 | 
			
		||||
		signer: Option<Arc<SignerService>>,
 | 
			
		||||
		ws_address: Option<Host>,
 | 
			
		||||
		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<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
 | 
			
		||||
		Err(errors::light_unimplemented(None))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn node_health(&self) -> BoxFuture<Health> {
 | 
			
		||||
		Box::new(self.health.health()
 | 
			
		||||
			.map_err(|err| errors::internal("Health API failure.", err)))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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<C, M, U> {
 | 
			
		||||
	updater: Arc<U>,
 | 
			
		||||
	sync: Arc<SyncProvider>,
 | 
			
		||||
	net: Arc<ManageNetwork>,
 | 
			
		||||
	health: NodeHealth,
 | 
			
		||||
	accounts: Arc<AccountProvider>,
 | 
			
		||||
	logger: Arc<RotatingLogger>,
 | 
			
		||||
	settings: Arc<NetworkSettings>,
 | 
			
		||||
@ -77,7 +75,6 @@ impl<C, M, U> ParityClient<C, M, U> where
 | 
			
		||||
		sync: Arc<SyncProvider>,
 | 
			
		||||
		updater: Arc<U>,
 | 
			
		||||
		net: Arc<ManageNetwork>,
 | 
			
		||||
		health: NodeHealth,
 | 
			
		||||
		accounts: Arc<AccountProvider>,
 | 
			
		||||
		logger: Arc<RotatingLogger>,
 | 
			
		||||
		settings: Arc<NetworkSettings>,
 | 
			
		||||
@ -91,7 +88,6 @@ impl<C, M, U> ParityClient<C, M, U> where
 | 
			
		||||
			sync,
 | 
			
		||||
			updater,
 | 
			
		||||
			net,
 | 
			
		||||
			health,
 | 
			
		||||
			accounts,
 | 
			
		||||
			logger,
 | 
			
		||||
			settings,
 | 
			
		||||
@ -466,9 +462,4 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
 | 
			
		||||
				.map(|res| res.into_iter().map(|res| res.output.into()).collect())
 | 
			
		||||
				.map_err(errors::call)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn node_health(&self) -> BoxFuture<Health> {
 | 
			
		||||
		Box::new(self.health.health()
 | 
			
		||||
			.map_err(|err| errors::internal("Health API failure.", err)))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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<TestBlockChainClient>,
 | 
			
		||||
	pub sync: Arc<TestSyncProvider>,
 | 
			
		||||
	pub updater: Arc<TestUpdater>,
 | 
			
		||||
	pub health: NodeHealth,
 | 
			
		||||
	pub logger: Arc<RotatingLogger>,
 | 
			
		||||
	pub settings: Arc<NetworkSettings>,
 | 
			
		||||
	pub network: Arc<ManageNetwork>,
 | 
			
		||||
@ -57,11 +54,6 @@ impl Dependencies {
 | 
			
		||||
				network_id: 3,
 | 
			
		||||
				num_peers: 120,
 | 
			
		||||
			})),
 | 
			
		||||
			health: NodeHealth::new(
 | 
			
		||||
				Arc::new(FakeSync),
 | 
			
		||||
				node_health::TimeChecker::new::<String>(&[], 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()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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<CallRequest>, Trailing<BlockNumber>) -> Result<Vec<Bytes>>;
 | 
			
		||||
 | 
			
		||||
		/// Returns node's health report.
 | 
			
		||||
		#[rpc(name = "parity_nodeHealth")]
 | 
			
		||||
		fn node_health(&self) -> BoxFuture<Health>;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user