From 5f5f26de48f8566237b0bab911f8ecdf25711bb4 Mon Sep 17 00:00:00 2001 From: arkpar Date: Sun, 10 Jan 2016 15:08:57 +0100 Subject: [PATCH] Do not insert new blocks out of order --- src/sync/chain.rs | 52 +++++++++++++++++++++++++---------------------- src/sync/io.rs | 11 +++++----- src/sync/tests.rs | 7 ++++--- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/sync/chain.rs b/src/sync/chain.rs index 95505ff81..bfbf3cfb8 100644 --- a/src/sync/chain.rs +++ b/src/sync/chain.rs @@ -386,31 +386,35 @@ impl ChainSync { let h = header_rlp.as_raw().sha3(); trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); - match io.chain().import_block(block_rlp.as_raw()) { - ImportResult::AlreadyInChain => { - trace!(target: "sync", "New block already in chain {:?}", h); - }, - ImportResult::AlreadyQueued(_) => { - trace!(target: "sync", "New block already queued {:?}", h); - }, - ImportResult::Queued(QueueStatus::Known) => { - trace!(target: "sync", "New block queued {:?}", h); - }, - ImportResult::Queued(QueueStatus::Unknown) => { - trace!(target: "sync", "New block unknown {:?}", h); - //TODO: handle too many unknown blocks - let difficulty: U256 = try!(r.val_at(1)); - let peer_difficulty = self.peers.get_mut(&peer_id).expect("ChainSync: unknown peer").difficulty; - if difficulty > peer_difficulty { - trace!(target: "sync", "Received block {:?} with no known parent. Peer needs syncing...", h); - self.sync_peer(io, peer_id, true); + let header_view = HeaderView::new(header_rlp.as_raw()); + // TODO: Decompose block and add to self.headers and self.bodies instead + if header_view.number() == From::from(self.last_imported_block + 1) { + match io.chain().import_block(block_rlp.as_raw()) { + ImportResult::AlreadyInChain => { + trace!(target: "sync", "New block already in chain {:?}", h); + }, + ImportResult::AlreadyQueued(_) => { + trace!(target: "sync", "New block already queued {:?}", h); + }, + ImportResult::Queued(QueueStatus::Known) => { + trace!(target: "sync", "New block queued {:?}", h); + }, + ImportResult::Queued(QueueStatus::Unknown) => { + trace!(target: "sync", "New block unknown {:?}", h); + //TODO: handle too many unknown blocks + let difficulty: U256 = try!(r.val_at(1)); + let peer_difficulty = self.peers.get_mut(&peer_id).expect("ChainSync: unknown peer").difficulty; + if difficulty > peer_difficulty { + trace!(target: "sync", "Received block {:?} with no known parent. Peer needs syncing...", h); + self.sync_peer(io, peer_id, true); + } + }, + ImportResult::Bad =>{ + debug!(target: "sync", "Bad new block {:?}", h); + io.disable_peer(peer_id); } - }, - ImportResult::Bad =>{ - debug!(target: "sync", "Bad new block {:?}", h); - io.disable_peer(peer_id); - } - }; + }; + } Ok(()) } diff --git a/src/sync/io.rs b/src/sync/io.rs index 54bd22f14..ed7b0fec5 100644 --- a/src/sync/io.rs +++ b/src/sync/io.rs @@ -1,10 +1,11 @@ use client::BlockChainClient; -use util::network::{HandlerIo, PeerId, PacketId, Error as NetworkError}; +use util::network::{HandlerIo, PeerId, PacketId,}; +use util::error::UtilError; pub trait SyncIo { fn disable_peer(&mut self, peer_id: &PeerId); - fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), NetworkError>; - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), NetworkError>; + fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), UtilError>; + fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError>; fn chain<'s>(&'s mut self) -> &'s mut BlockChainClient; } @@ -27,11 +28,11 @@ impl<'s, 'h> SyncIo for NetSyncIo<'s, 'h> { self.network.disable_peer(*peer_id); } - fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), NetworkError>{ + fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), UtilError>{ self.network.respond(packet_id, data) } - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), NetworkError>{ + fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError>{ self.network.send(peer_id, packet_id, data) } diff --git a/src/sync/tests.rs b/src/sync/tests.rs index 28e526aa9..dfcf75c8b 100644 --- a/src/sync/tests.rs +++ b/src/sync/tests.rs @@ -4,7 +4,8 @@ use util::hash::{H256, FixedHash}; use util::uint::{U256}; use util::sha3::Hashable; use util::rlp::{self, Rlp, RlpStream, View, Stream}; -use util::network::{PeerId, PacketId, Error as NetworkError}; +use util::network::{PeerId, PacketId}; +use util::error::UtilError; use client::{BlockChainClient, BlockStatus, BlockNumber, TreeRoute, BlockQueueStatus, BlockChainInfo, ImportResult, QueueStatus}; use header::Header as BlockHeader; use sync::io::SyncIo; @@ -195,7 +196,7 @@ impl<'p> SyncIo for TestIo<'p> { fn disable_peer(&mut self, _peer_id: &PeerId) { } - fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), NetworkError> { + fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { self.queue.push_back(TestPacket { data: data, packet_id: packet_id, @@ -204,7 +205,7 @@ impl<'p> SyncIo for TestIo<'p> { Ok(()) } - fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), NetworkError> { + fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { self.queue.push_back(TestPacket { data: data, packet_id: packet_id,