From 6d497f61c65b1c02c4cfb5f4e0673574a0cd17d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 2 Jun 2015 15:57:07 +0300 Subject: [PATCH] eth/downloader: don't block hash deliveries while pulling blocks --- eth/downloader/downloader.go | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 159a06bd4..4b837eed5 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -418,6 +418,9 @@ out: case <-d.cancelCh: return errCancelBlockFetch + case <-d.hashCh: + // Out of bounds hashes received, ignore them + case blockPack := <-d.blockCh: // Short circuit if it's a stale cross check if len(blockPack.blocks) == 1 { @@ -472,30 +475,21 @@ out: glog.V(logger.Detail).Infof("%s: delivery partially failed: %v", peer, err) } } + case <-ticker.C: - // Check for bad peers. Bad peers may indicate a peer not responding - // to a `getBlocks` message. A timeout of 5 seconds is set. Peers - // that badly or poorly behave are removed from the peer set (not banned). - // Bad peers are excluded from the available peer set and therefor won't be - // reused. XXX We could re-introduce peers after X time. + // Short circuit if we lost all our peers + if d.peers.Len() == 0 { + return errNoPeers + } + // Check for block request timeouts and demote the responsible peers badPeers := d.queue.Expire(blockHardTTL) for _, pid := range badPeers { - // XXX We could make use of a reputation system here ranking peers - // in their performance - // 1) Time for them to respond; - // 2) Measure their speed; - // 3) Amount and availability. if peer := d.peers.Peer(pid); peer != nil { peer.Demote() glog.V(logger.Detail).Infof("%s: block delivery timeout", peer) } } - // After removing bad peers make sure we actually have sufficient peer left to keep downloading - if d.peers.Len() == 0 { - return errNoPeers - } - // If there are unrequested hashes left start fetching - // from the available peers. + // If there are unrequested hashes left start fetching from the available peers if d.queue.Pending() > 0 { // Throttle the download if block cache is full and waiting processing if d.queue.Throttle() { @@ -565,7 +559,7 @@ func (d *Downloader) banBlocks(peerId string, head common.Hash) error { return err } // Wait a bit for the reply to arrive, and ban if done so - timeout := time.After(blockTTL) + timeout := time.After(blockHardTTL) for { select { case <-d.cancelCh: @@ -574,6 +568,9 @@ func (d *Downloader) banBlocks(peerId string, head common.Hash) error { case <-timeout: return ErrTimeout + case <-d.hashCh: + // Out of bounds hashes received, ignore them + case blockPack := <-d.blockCh: blocks := blockPack.blocks