Don't block sync when importing old blocks (#8530)

* Alter IO queueing.

* Don't require IoMessages to be Clone

* Ancient blocks imported via IoChannel.

* Get rid of private transactions io message.

* Get rid of deadlock and fix disconnected handler.

* Revert to old disconnect condition.

* Fix tests.

* Fix deadlock.
This commit is contained in:
Tomasz Drwięga
2018-05-09 08:49:34 +02:00
committed by Afri Schoedon
parent 7a00d97977
commit 24838bbcd3
23 changed files with 455 additions and 332 deletions

View File

@@ -13,6 +13,7 @@ ethcore-sync = { path = "../sync" }
kvdb = { path = "../../util/kvdb" }
log = "0.3"
stop-guard = { path = "../../util/stop-guard" }
trace-time = { path = "../../util/trace-time" }
[dev-dependencies]
tempdir = "0.3"

View File

@@ -28,6 +28,9 @@ extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate trace_time;
#[cfg(test)]
extern crate tempdir;

View File

@@ -33,7 +33,7 @@ use ethcore::snapshot::{RestorationStatus};
use ethcore::spec::Spec;
use ethcore::account_provider::AccountProvider;
use ethcore_private_tx;
use ethcore_private_tx::{self, Importer};
use Error;
pub struct PrivateTxService {
@@ -112,14 +112,13 @@ impl ClientService {
account_provider,
encryptor,
private_tx_conf,
io_service.channel())?,
);
io_service.channel(),
));
let private_tx = Arc::new(PrivateTxService::new(provider));
let client_io = Arc::new(ClientIoHandler {
client: client.clone(),
snapshot: snapshot.clone(),
private_tx: private_tx.clone(),
});
io_service.register_handler(client_io)?;
@@ -175,7 +174,6 @@ impl ClientService {
struct ClientIoHandler {
client: Arc<Client>,
snapshot: Arc<SnapshotService>,
private_tx: Arc<PrivateTxService>,
}
const CLIENT_TICK_TIMER: TimerToken = 0;
@@ -191,6 +189,7 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
}
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
trace_time!("service::read");
match timer {
CLIENT_TICK_TIMER => {
use ethcore::snapshot::SnapshotService;
@@ -203,20 +202,24 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
}
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
trace_time!("service::message");
use std::thread;
match *net_message {
ClientIoMessage::BlockVerified => { self.client.import_verified_blocks(); }
ClientIoMessage::NewTransactions(ref transactions, peer_id) => {
self.client.import_queued_transactions(transactions, peer_id);
ClientIoMessage::BlockVerified => {
self.client.import_verified_blocks();
}
ClientIoMessage::BeginRestoration(ref manifest) => {
if let Err(e) = self.snapshot.init_restore(manifest.clone(), true) {
warn!("Failed to initialize snapshot restoration: {}", e);
}
}
ClientIoMessage::FeedStateChunk(ref hash, ref chunk) => self.snapshot.feed_state_chunk(*hash, chunk),
ClientIoMessage::FeedBlockChunk(ref hash, ref chunk) => self.snapshot.feed_block_chunk(*hash, chunk),
ClientIoMessage::FeedStateChunk(ref hash, ref chunk) => {
self.snapshot.feed_state_chunk(*hash, chunk)
}
ClientIoMessage::FeedBlockChunk(ref hash, ref chunk) => {
self.snapshot.feed_block_chunk(*hash, chunk)
}
ClientIoMessage::TakeSnapshot(num) => {
let client = self.client.clone();
let snapshot = self.snapshot.clone();
@@ -231,12 +234,9 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
debug!(target: "snapshot", "Failed to initialize periodic snapshot thread: {:?}", e);
}
},
ClientIoMessage::NewMessage(ref message) => if let Err(e) = self.client.engine().handle_message(message) {
trace!(target: "poa", "Invalid message received: {}", e);
},
ClientIoMessage::NewPrivateTransaction => if let Err(e) = self.private_tx.provider.on_private_transaction_queued() {
warn!("Failed to handle private transaction {:?}", e);
},
ClientIoMessage::Execute(ref exec) => {
(*exec.0)(&self.client);
}
_ => {} // ignore other messages
}
}