aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
Diffstat (limited to 'eth')
-rw-r--r--eth/downloader/downloader.go10
-rw-r--r--eth/downloader/peer.go9
2 files changed, 16 insertions, 3 deletions
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index 1b9b7d01b..206c4cc7e 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -268,8 +268,14 @@ out:
chunk := d.queue.get(peer, maxBlockFetch)
if chunk != nil {
//fmt.Println("fetching for", peer.id)
- // Fetch the chunk.
- peer.fetch(chunk)
+ // Fetch the chunk and check for error. If the peer was somehow
+ // already fetching a chunk due to a bug, it will be returned to
+ // the queue
+ if err := peer.fetch(chunk); err != nil {
+ // log for tracing
+ glog.V(logger.Debug).Infof("peer %s received double work (state = %v)\n", peer.id, peer.state)
+ d.queue.put(chunk.hashes)
+ }
}
}
atomic.StoreInt32(&d.downloadingBlocks, 1)
diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go
index 486c09e38..318da59b7 100644
--- a/eth/downloader/peer.go
+++ b/eth/downloader/peer.go
@@ -1,6 +1,7 @@
package downloader
import (
+ "errors"
"math/big"
"sync"
@@ -31,10 +32,14 @@ func newPeer(id string, td *big.Int, hash common.Hash, getHashes hashFetcherFn,
}
// fetch a chunk using the peer
-func (p *peer) fetch(chunk *chunk) {
+func (p *peer) fetch(chunk *chunk) error {
p.mu.Lock()
defer p.mu.Unlock()
+ if p.state == workingState {
+ return errors.New("peer already fetching chunk")
+ }
+
// set working state
p.state = workingState
// convert the set to a fetchable slice
@@ -45,4 +50,6 @@ func (p *peer) fetch(chunk *chunk) {
return true
})
p.getBlocks(hashes)
+
+ return nil
}