diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 1ae1d04ca..28a5ab90f 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -140,6 +140,8 @@ const HEADERS_TIMEOUT_SEC: f64 = 15f64; const BODIES_TIMEOUT_SEC: f64 = 10f64; const FORK_HEADER_TIMEOUT_SEC: f64 = 3f64; +const MAX_REORG_BLOCKS: u64 = 64; + #[derive(Copy, Clone, Eq, PartialEq, Debug)] /// Sync state pub enum SyncState { @@ -567,6 +569,12 @@ impl ChainSync { trace!(target: "sync", "Received {} subchain heads, proceeding to download", headers.len()); self.blocks.reset_to(hashes); self.state = SyncState::Blocks; + } 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"); + io.disable_peer(peer_id); + } } }, SyncState::Blocks | SyncState::NewBlocks | SyncState::Waiting => { diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index c54529beb..4cd10a488 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -78,14 +78,14 @@ fn empty_blocks() { fn forked() { ::env_logger::init().ok(); let mut net = TestNet::new(3); - net.peer_mut(0).chain.add_blocks(300, EachBlockWith::Uncle); - net.peer_mut(1).chain.add_blocks(300, EachBlockWith::Uncle); - net.peer_mut(2).chain.add_blocks(300, EachBlockWith::Uncle); - net.peer_mut(0).chain.add_blocks(100, EachBlockWith::Nothing); //fork - net.peer_mut(1).chain.add_blocks(200, EachBlockWith::Uncle); - net.peer_mut(2).chain.add_blocks(200, EachBlockWith::Uncle); - net.peer_mut(1).chain.add_blocks(100, EachBlockWith::Uncle); //fork between 1 and 2 - net.peer_mut(2).chain.add_blocks(10, EachBlockWith::Nothing); + net.peer_mut(0).chain.add_blocks(30, EachBlockWith::Uncle); + net.peer_mut(1).chain.add_blocks(30, EachBlockWith::Uncle); + net.peer_mut(2).chain.add_blocks(30, EachBlockWith::Uncle); + net.peer_mut(0).chain.add_blocks(10, EachBlockWith::Nothing); //fork + net.peer_mut(1).chain.add_blocks(20, EachBlockWith::Uncle); + net.peer_mut(2).chain.add_blocks(20, EachBlockWith::Uncle); + net.peer_mut(1).chain.add_blocks(10, EachBlockWith::Uncle); //fork between 1 and 2 + net.peer_mut(2).chain.add_blocks(1, EachBlockWith::Nothing); // peer 1 has the best chain of 601 blocks let peer1_chain = net.peer(1).chain.numbers.read().clone(); net.sync();