eth/downloader: reject peer registration if head is banned
This commit is contained in:
parent
63c6cedb14
commit
c4f224932f
|
@ -36,6 +36,7 @@ var (
|
||||||
errUnknownPeer = errors.New("peer is unknown or unhealthy")
|
errUnknownPeer = errors.New("peer is unknown or unhealthy")
|
||||||
ErrBadPeer = errors.New("action from bad peer ignored")
|
ErrBadPeer = errors.New("action from bad peer ignored")
|
||||||
ErrStallingPeer = errors.New("peer is stalling")
|
ErrStallingPeer = errors.New("peer is stalling")
|
||||||
|
errBannedHead = errors.New("peer head hash already banned")
|
||||||
errNoPeers = errors.New("no peers to keep download active")
|
errNoPeers = errors.New("no peers to keep download active")
|
||||||
ErrPendingQueue = errors.New("pending items in queue")
|
ErrPendingQueue = errors.New("pending items in queue")
|
||||||
ErrTimeout = errors.New("timeout")
|
ErrTimeout = errors.New("timeout")
|
||||||
|
@ -72,11 +73,10 @@ type crossCheck struct {
|
||||||
type Downloader struct {
|
type Downloader struct {
|
||||||
mux *event.TypeMux
|
mux *event.TypeMux
|
||||||
|
|
||||||
mu sync.RWMutex
|
|
||||||
queue *queue // Scheduler for selecting the hashes to download
|
queue *queue // Scheduler for selecting the hashes to download
|
||||||
peers *peerSet // Set of active peers from which download can proceed
|
peers *peerSet // Set of active peers from which download can proceed
|
||||||
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
||||||
banned *set.SetNonTS // Set of hashes we've received and banned
|
banned *set.Set // Set of hashes we've received and banned
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
hasBlock hashCheckFn
|
hasBlock hashCheckFn
|
||||||
|
@ -114,7 +114,7 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloa
|
||||||
blockCh: make(chan blockPack, 1),
|
blockCh: make(chan blockPack, 1),
|
||||||
}
|
}
|
||||||
// Inject all the known bad hashes
|
// Inject all the known bad hashes
|
||||||
downloader.banned = set.NewNonTS()
|
downloader.banned = set.New()
|
||||||
for hash, _ := range core.BadHashes {
|
for hash, _ := range core.BadHashes {
|
||||||
downloader.banned.Add(hash)
|
downloader.banned.Add(hash)
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,12 @@ func (d *Downloader) Synchronising() bool {
|
||||||
// RegisterPeer injects a new download peer into the set of block source to be
|
// RegisterPeer injects a new download peer into the set of block source to be
|
||||||
// used for fetching hashes and blocks from.
|
// used for fetching hashes and blocks from.
|
||||||
func (d *Downloader) RegisterPeer(id string, head common.Hash, getHashes hashFetcherFn, getBlocks blockFetcherFn) error {
|
func (d *Downloader) RegisterPeer(id string, head common.Hash, getHashes hashFetcherFn, getBlocks blockFetcherFn) error {
|
||||||
|
// If the peer wants to send a banned hash, reject
|
||||||
|
if d.banned.Has(head) {
|
||||||
|
glog.V(logger.Debug).Infoln("Register rejected, head hash banned:", id)
|
||||||
|
return errBannedHead
|
||||||
|
}
|
||||||
|
// Otherwise try to construct and register the peer
|
||||||
glog.V(logger.Detail).Infoln("Registering peer", id)
|
glog.V(logger.Detail).Infoln("Registering peer", id)
|
||||||
if err := d.peers.Register(newPeer(id, head, getHashes, getBlocks)); err != nil {
|
if err := d.peers.Register(newPeer(id, head, getHashes, getBlocks)); err != nil {
|
||||||
glog.V(logger.Error).Infoln("Register failed:", err)
|
glog.V(logger.Error).Infoln("Register failed:", err)
|
||||||
|
@ -199,6 +205,8 @@ func (d *Downloader) TakeBlocks() []*Block {
|
||||||
return d.queue.TakeBlocks()
|
return d.queue.TakeBlocks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has checks if the downloader knows about a particular hash, meaning that its
|
||||||
|
// either already downloaded of pending retrieval.
|
||||||
func (d *Downloader) Has(hash common.Hash) bool {
|
func (d *Downloader) Has(hash common.Hash) bool {
|
||||||
return d.queue.Has(hash)
|
return d.queue.Has(hash)
|
||||||
}
|
}
|
||||||
|
@ -604,14 +612,17 @@ func (d *Downloader) banBlocks(peerId string, head common.Hash) error {
|
||||||
// Ban the head hash and phase out any excess
|
// Ban the head hash and phase out any excess
|
||||||
d.banned.Add(blocks[index].Hash())
|
d.banned.Add(blocks[index].Hash())
|
||||||
for d.banned.Size() > maxBannedHashes {
|
for d.banned.Size() > maxBannedHashes {
|
||||||
|
var evacuate common.Hash
|
||||||
|
|
||||||
d.banned.Each(func(item interface{}) bool {
|
d.banned.Each(func(item interface{}) bool {
|
||||||
// Skip any hard coded bans
|
// Skip any hard coded bans
|
||||||
if core.BadHashes[item.(common.Hash)] {
|
if core.BadHashes[item.(common.Hash)] {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
d.banned.Remove(item)
|
evacuate = item.(common.Hash)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
d.banned.Remove(evacuate)
|
||||||
}
|
}
|
||||||
glog.V(logger.Debug).Infof("Banned %d blocks from: %s", index+1, peerId)
|
glog.V(logger.Debug).Infof("Banned %d blocks from: %s", index+1, peerId)
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue