downloader: return an error for peer.fetch and return chunk to queue

If a peer was somehow already fetching and somehow managed to end up in
the `available` pool it should return it's work.
pull/709/head
obscuren 10 years ago
parent 6efa8db888
commit 7dcb9825c3
  1. 10
      eth/downloader/downloader.go
  2. 9
      eth/downloader/peer.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)

@ -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
}

Loading…
Cancel
Save