diff --git a/sync/src/block_sync.rs b/sync/src/block_sync.rs index ff5411140..eea977906 100644 --- a/sync/src/block_sync.rs +++ b/sync/src/block_sync.rs @@ -258,6 +258,12 @@ impl BlockDownloader { self.blocks.reset_to(hashes); self.state = State::Blocks; return Ok(DownloadAction::Reset); + } else { + let best = io.chain().chain_info().best_block_number; + if best > self.last_imported_block && best - self.last_imported_block > MAX_REORG_BLOCKS { + trace!(target: "sync", "No common block, disabling peer"); + return Err(BlockDownloaderImportError::Invalid); + } } }, State::Blocks => { diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 5fe34428e..7705215f5 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -250,3 +250,14 @@ fn high_td_attach() { assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5); } + +#[test] +fn disconnect_on_unrelated_chain() { + ::env_logger::init().ok(); + let mut net = TestNet::new(2); + net.peer_mut(0).chain.add_blocks(200, EachBlockWith::Uncle); + net.peer_mut(1).chain.add_blocks(100, EachBlockWith::Nothing); + net.sync(); + assert_eq!(net.disconnect_events, vec![(0, 0)]); +} + diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index d5e07a936..b1c04f84e 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -123,6 +123,7 @@ pub struct TestPeer { pub struct TestNet { pub peers: Vec, pub started: bool, + pub disconnect_events: Vec<(PeerId, PeerId)>, //disconnected (initiated by, to) } impl TestNet { @@ -140,6 +141,7 @@ impl TestNet { let mut net = TestNet { peers: Vec::new(), started: false, + disconnect_events: Vec::new(), }; for _ in 0..n { let chain = TestBlockChainClient::new(); @@ -190,6 +192,7 @@ impl TestNet { // notify this that disconnecting peers are disconnecting let mut io = TestIo::new(&mut p.chain, &p.snapshot_service, &mut p.queue, Some(*d)); p.sync.write().on_peer_aborting(&mut io, *d); + self.disconnect_events.push((peer, *d)); } to_disconnect };