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

@@ -379,10 +379,12 @@ impl NetworkProtocolHandler for SyncProtocolHandler {
}
fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) {
trace_time!("sync::read");
ChainSync::dispatch_packet(&self.sync, &mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay), *peer, packet_id, data);
}
fn connected(&self, io: &NetworkContext, peer: &PeerId) {
trace_time!("sync::connected");
// If warp protocol is supported only allow warp handshake
let warp_protocol = io.protocol_version(WARP_SYNC_PROTOCOL_ID, *peer).unwrap_or(0) != 0;
let warp_context = io.subprotocol_name() == WARP_SYNC_PROTOCOL_ID;
@@ -392,12 +394,14 @@ impl NetworkProtocolHandler for SyncProtocolHandler {
}
fn disconnected(&self, io: &NetworkContext, peer: &PeerId) {
trace_time!("sync::disconnected");
if io.subprotocol_name() != WARP_SYNC_PROTOCOL_ID {
self.sync.write().on_peer_aborting(&mut NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay), *peer);
}
}
fn timeout(&self, io: &NetworkContext, _timer: TimerToken) {
trace_time!("sync::timeout");
let mut io = NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay);
self.sync.write().maintain_peers(&mut io);
self.sync.write().maintain_sync(&mut io);

View File

@@ -496,7 +496,7 @@ impl BlockDownloader {
}
let result = if let Some(receipts) = receipts {
io.chain().import_block_with_receipts(block, receipts)
io.chain().queue_ancient_block(block, receipts)
} else {
io.chain().import_block(block)
};

View File

@@ -1789,10 +1789,13 @@ impl ChainSync {
}
pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) {
debug!(target: "sync", "{} -> Dispatching packet: {}", peer, packet_id);
if packet_id != STATUS_PACKET && !self.peers.contains_key(&peer) {
debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer));
return;
}
let rlp = Rlp::new(data);
let result = match packet_id {
STATUS_PACKET => self.on_peer_status(io, peer, &rlp),
@@ -1831,7 +1834,7 @@ impl ChainSync {
PeerAsking::SnapshotData => elapsed > SNAPSHOT_DATA_TIMEOUT,
};
if timeout {
trace!(target:"sync", "Timeout {}", peer_id);
debug!(target:"sync", "Timeout {}", peer_id);
io.disconnect_peer(*peer_id);
aborting.push(*peer_id);
}

View File

@@ -54,6 +54,8 @@ extern crate macros;
extern crate log;
#[macro_use]
extern crate heapsize;
#[macro_use]
extern crate trace_time;
mod chain;
mod blocks;

View File

@@ -520,11 +520,9 @@ impl TestIoHandler {
impl IoHandler<ClientIoMessage> for TestIoHandler {
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
match *net_message {
ClientIoMessage::NewMessage(ref message) => if let Err(e) = self.client.engine().handle_message(message) {
panic!("Invalid message received: {}", e);
},
ClientIoMessage::NewPrivateTransaction => {
ClientIoMessage::Execute(ref exec) => {
*self.private_tx_queued.lock() += 1;
(*exec.0)(&self.client);
},
_ => {} // ignore other messages
}

View File

@@ -24,7 +24,7 @@ use ethcore::CreateContractAddress;
use transaction::{Transaction, Action};
use ethcore::executive::{contract_address};
use ethcore::test_helpers::{push_block_with_transactions};
use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor};
use ethcore_private_tx::{Provider, ProviderConfig, NoopEncryptor, Importer};
use ethcore::account_provider::AccountProvider;
use ethkey::{KeyPair};
use tests::helpers::{TestNet, TestIoHandler};
@@ -84,7 +84,7 @@ fn send_private_transaction() {
Box::new(NoopEncryptor::default()),
signer_config,
IoChannel::to_handler(Arc::downgrade(&io_handler0)),
).unwrap());
));
pm0.add_notify(net.peers[0].clone());
let pm1 = Arc::new(Provider::new(
@@ -94,7 +94,7 @@ fn send_private_transaction() {
Box::new(NoopEncryptor::default()),
validator_config,
IoChannel::to_handler(Arc::downgrade(&io_handler1)),
).unwrap());
));
pm1.add_notify(net.peers[1].clone());
// Create and deploy contract
@@ -133,7 +133,6 @@ fn send_private_transaction() {
//process received private transaction message
let private_transaction = received_private_transactions[0].clone();
assert!(pm1.import_private_transaction(&private_transaction).is_ok());
assert!(pm1.on_private_transaction_queued().is_ok());
//send signed response
net.sync();
@@ -147,4 +146,4 @@ fn send_private_transaction() {
assert!(pm0.import_signed_private_transaction(&signed_private_transaction).is_ok());
let local_transactions = net.peer(0).miner.local_transactions();
assert_eq!(local_transactions.len(), 1);
}
}