Major sync <-> client interactions refactoring (#1572)

* chain notify trait

* replaced network service with io service

* fix ethcore crate warnings

* refactored network service without generic

* ethcore fix

* ethsync refactoring

* proper linking of notify

* manage network interface

* rpc crate rebinding

* full rewire

* sync internal io service

* fix deadlock

* fix warnings and removed async io

* sync imported message propagation

* fix rpc warnings

* binart warnings

* test fixes

* rpc mocks and tests

* fix util doctest

* fix message name and removed empty notifier

* pointers mess & dark mode fixed

* fixed sync doctest

* added few warnings

* fix review

* new convention match

* fix error unwraps

* doctest fix
This commit is contained in:
Nikolay Volf
2016-07-11 17:02:42 +02:00
committed by Arkadiy Paronyan
parent 2382d779ca
commit d3695d0b72
23 changed files with 469 additions and 418 deletions

View File

@@ -21,8 +21,8 @@ use self::ansi_term::Style;
use std::time::{Instant, Duration};
use std::sync::RwLock;
use std::ops::{Deref, DerefMut};
use ethsync::{EthSync, SyncProvider};
use util::{Uint, RwLockable, NetworkService};
use ethsync::SyncStatus;
use util::{Uint, RwLockable, NetworkConfiguration};
use ethcore::client::*;
use number_prefix::{binary_prefix, Standalone, Prefixed};
@@ -75,7 +75,8 @@ impl Informant {
}
}
pub fn tick<Message>(&self, client: &Client, maybe_sync: Option<(&EthSync, &NetworkService<Message>)>) where Message: Send + Sync + Clone + 'static {
#[cfg_attr(feature="dev", allow(match_bool))]
pub fn tick(&self, client: &Client, maybe_status: Option<(SyncStatus, NetworkConfiguration)>) {
let elapsed = self.last_tick.unwrapped_read().elapsed();
if elapsed < Duration::from_secs(5) {
return;
@@ -108,10 +109,8 @@ impl Informant {
paint(Yellow.bold(), format!("{:4}", ((report.transactions_applied - last_report.transactions_applied) * 1000) as u64 / elapsed.as_milliseconds())),
paint(Yellow.bold(), format!("{:3}", ((report.gas_processed - last_report.gas_processed) / From::from(elapsed.as_milliseconds() * 1000)).low_u64())),
match maybe_sync {
Some((sync, net)) => {
let sync_info = sync.status();
let net_config = net.config();
match maybe_status {
Some((ref sync_info, ref net_config)) => {
format!("{}/{}/{} peers {} ",
paint(Green.bold(), format!("{:2}", sync_info.num_active_peers)),
paint(Green.bold(), format!("{:2}", sync_info.num_peers)),
@@ -128,13 +127,9 @@ impl Informant {
paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(report.state_db_mem))),
paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(cache_info.total()))),
paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(queue_info.mem_used))),
match maybe_sync {
Some((sync, _)) => {
let sync_info = sync.status();
format!(" {} sync", paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used))))
}
None => String::new()
},
if let Some((ref sync_info, _)) = maybe_status {
format!(" {} sync", paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used))))
} else { String::new() },
);
}

View File

@@ -14,12 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::{Arc, Weak};
use std::sync::Arc;
use ethcore::client::Client;
use ethcore::service::{NetSyncMessage, SyncMessage};
use ethsync::EthSync;
use ethcore::service::ClientIoMessage;
use ethsync::{EthSync, SyncProvider, ManageNetwork};
use ethcore::account_provider::AccountProvider;
use util::{TimerToken, IoHandler, IoContext, NetworkService, NetworkIoMessage};
use util::{TimerToken, IoHandler, IoContext};
use informant::Informant;
@@ -30,38 +30,18 @@ pub struct ClientIoHandler {
pub sync: Arc<EthSync>,
pub accounts: Arc<AccountProvider>,
pub info: Informant,
pub network: Weak<NetworkService<SyncMessage>>,
}
impl IoHandler<NetSyncMessage> for ClientIoHandler {
fn initialize(&self, io: &IoContext<NetSyncMessage>) {
impl IoHandler<ClientIoMessage> for ClientIoHandler {
fn initialize(&self, io: &IoContext<ClientIoMessage>) {
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
}
fn timeout(&self, _io: &IoContext<NetSyncMessage>, timer: TimerToken) {
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
if let INFO_TIMER = timer {
if let Some(net) = self.network.upgrade() {
self.info.tick(&self.client, Some((&self.sync, &net)));
}
}
}
fn message(&self, _io: &IoContext<NetSyncMessage>, message: &NetSyncMessage) {
match *message {
NetworkIoMessage::User(SyncMessage::StartNetwork) => {
if let Some(network) = self.network.upgrade() {
network.start().unwrap_or_else(|e| warn!("Error starting network: {:?}", e));
EthSync::register(&*network, self.sync.clone()).unwrap_or_else(|e| warn!("Error registering eth protocol handler: {}", e));
}
},
NetworkIoMessage::User(SyncMessage::StopNetwork) => {
if let Some(network) = self.network.upgrade() {
network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e));
}
},
_ => {/* Ignore other messages */},
let sync_status = self.sync.status();
let network_config = self.sync.network_config();
self.info.tick(&self.client, Some((sync_status, network_config)));
}
}
}

View File

@@ -81,9 +81,10 @@ use std::thread::sleep;
use std::time::Duration;
use rustc_serialize::hex::FromHex;
use ctrlc::CtrlC;
use util::{Lockable, H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes, UtilError, Colour, Applyable, version, journaldb};
use util::{Lockable, H256, ToPretty, PayloadInfo, Bytes, Colour, Applyable, version, journaldb};
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
use ethcore::client::{Mode, BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError};
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError,
ChainNotify, Mode};
use ethcore::error::{ImportError};
use ethcore::service::ClientService;
use ethcore::spec::Spec;
@@ -231,13 +232,11 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
miner.set_transactions_limit(conf.args.flag_tx_queue_size);
// Build client
let mut service = ClientService::start(
let service = ClientService::start(
client_config,
spec,
net_settings,
Path::new(&conf.path()),
miner.clone(),
match conf.mode() { Mode::Dark(..) => false, _ => !conf.args.flag_no_network }
).unwrap_or_else(|e| die_with_error("Client", e));
panic_handler.forward_from(&service);
@@ -247,8 +246,14 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
let network_settings = Arc::new(conf.network_settings());
// Sync
let sync = EthSync::new(sync_config, client.clone());
EthSync::register(&*service.network(), sync.clone()).unwrap_or_else(|e| die_with_error("Error registering eth protocol handler", UtilError::from(e).into()));
let sync = EthSync::new(sync_config, client.clone(), net_settings)
.unwrap_or_else(|e| die_with_error("Sync", ethcore::error::Error::Util(e)));
service.set_notify(&(sync.clone() as Arc<ChainNotify>));
// if network is active by default
if match conf.mode() { Mode::Dark(..) => false, _ => !conf.args.flag_no_network } {
sync.start();
}
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
signer_port: conf.signer_port(),
@@ -261,7 +266,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
logger: logger.clone(),
settings: network_settings.clone(),
allow_pending_receipt_query: !conf.args.flag_geth,
net_service: service.network(),
net_service: sync.clone(),
});
let dependencies = rpc::Dependencies {
@@ -311,7 +316,6 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
info: Informant::new(conf.have_color()),
sync: sync.clone(),
accounts: account_service.clone(),
network: Arc::downgrade(&service.network()),
});
service.register_io_handler(io_handler).expect("Error registering IO handler");
@@ -345,24 +349,11 @@ fn execute_export(conf: Configuration) {
unsafe { ::fdlimit::raise_fd_limit(); }
let spec = conf.spec();
let net_settings = NetworkConfiguration {
config_path: None,
listen_address: None,
public_address: None,
udp_port: None,
nat_enabled: false,
discovery_enabled: false,
boot_nodes: Vec::new(),
use_secret: None,
ideal_peers: 0,
reserved_nodes: Vec::new(),
non_reserved_mode: ::util::network::NonReservedPeerMode::Accept,
};
let client_config = conf.client_config(&spec);
// Build client
let service = ClientService::start(
client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec())), false
client_config, spec, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec()))
).unwrap_or_else(|e| die_with_error("Client", e));
panic_handler.forward_from(&service);
@@ -419,24 +410,11 @@ fn execute_import(conf: Configuration) {
unsafe { ::fdlimit::raise_fd_limit(); }
let spec = conf.spec();
let net_settings = NetworkConfiguration {
config_path: None,
listen_address: None,
public_address: None,
udp_port: None,
nat_enabled: false,
discovery_enabled: false,
boot_nodes: Vec::new(),
use_secret: None,
ideal_peers: 0,
reserved_nodes: Vec::new(),
non_reserved_mode: ::util::network::NonReservedPeerMode::Accept,
};
let client_config = conf.client_config(&spec);
// Build client
let service = ClientService::start(
client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec())), false
client_config, spec, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec()))
).unwrap_or_else(|e| die_with_error("Client", e));
panic_handler.forward_from(&service);
@@ -485,7 +463,7 @@ fn execute_import(conf: Configuration) {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { trace!("Skipping block already in chain."); }
Err(e) => die!("Cannot import block: {:?}", e)
}
informant.tick::<&'static ()>(client.deref(), None);
informant.tick(client.deref(), None);
};
match format {

View File

@@ -18,13 +18,12 @@ use std::collections::BTreeMap;
use std::str::FromStr;
use std::sync::Arc;
use ethsync::EthSync;
use ethsync::{EthSync, ManageNetwork};
use ethcore::miner::{Miner, ExternalMiner};
use ethcore::client::Client;
use util::RotatingLogger;
use ethcore::account_provider::AccountProvider;
use util::network_settings::NetworkSettings;
use util::network::NetworkService;
#[cfg(feature="rpc")]
pub use ethcore_rpc::ConfirmationsQueue;
@@ -89,7 +88,7 @@ pub struct Dependencies {
pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>,
pub allow_pending_receipt_query: bool,
pub net_service: Arc<NetworkService<::ethcore::service::SyncMessage>>,
pub net_service: Arc<ManageNetwork>,
}
fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {