aboutsummaryrefslogtreecommitdiffstats
path: root/eth/downloader/queue.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2015-09-15 18:33:45 +0800
committerPéter Szilágyi <peterke@gmail.com>2015-09-15 19:45:53 +0800
commit99b62f36b6443e8ed8ff4e8c09ee9267eeaea162 (patch)
tree1839f62c31897a62f9e190a4fbda27310a060825 /eth/downloader/queue.go
parent0a7d059b6a4365c671386855289bfdc3178e2d60 (diff)
downloaddexon-99b62f36b6443e8ed8ff4e8c09ee9267eeaea162.tar.gz
dexon-99b62f36b6443e8ed8ff4e8c09ee9267eeaea162.tar.zst
dexon-99b62f36b6443e8ed8ff4e8c09ee9267eeaea162.zip
eth/downloader: header-chain order and ancestry check
Diffstat (limited to 'eth/downloader/queue.go')
-rw-r--r--eth/downloader/queue.go17
1 files changed, 15 insertions, 2 deletions
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
index 7db78327b..49d1046fb 100644
--- a/eth/downloader/queue.go
+++ b/eth/downloader/queue.go
@@ -57,6 +57,7 @@ type queue struct {
headerPool map[common.Hash]*types.Header // [eth/62] Pending headers, mapping from their hashes
headerQueue *prque.Prque // [eth/62] Priority queue of the headers to fetch the bodies for
+ headerHead common.Hash // [eth/62] Hash of the last queued header to verify order
pendPool map[string]*fetchRequest // Currently pending block retrieval operations
@@ -91,6 +92,7 @@ func (q *queue) Reset() {
q.headerPool = make(map[common.Hash]*types.Header)
q.headerQueue.Reset()
+ q.headerHead = common.Hash{}
q.pendPool = make(map[string]*fetchRequest)
@@ -186,7 +188,7 @@ func (q *queue) Insert61(hashes []common.Hash, fifo bool) []common.Hash {
// Insert adds a set of headers for the download queue for scheduling, returning
// the new headers encountered.
-func (q *queue) Insert(headers []*types.Header) []*types.Header {
+func (q *queue) Insert(headers []*types.Header, from uint64) []*types.Header {
q.lock.Lock()
defer q.lock.Unlock()
@@ -196,13 +198,24 @@ func (q *queue) Insert(headers []*types.Header) []*types.Header {
// Make sure no duplicate requests are executed
hash := header.Hash()
if _, ok := q.headerPool[hash]; ok {
- glog.V(logger.Warn).Infof("Header %x already scheduled", hash)
+ glog.V(logger.Warn).Infof("Header #%d [%x] already scheduled", header.Number.Uint64(), hash[:4])
continue
}
+ // Make sure chain order is honored and preserved throughout
+ if header.Number == nil || header.Number.Uint64() != from {
+ glog.V(logger.Warn).Infof("Header #%v [%x] broke chain ordering, expected %d", header.Number, hash[:4], from)
+ break
+ }
+ if q.headerHead != (common.Hash{}) && q.headerHead != header.ParentHash {
+ glog.V(logger.Warn).Infof("Header #%v [%x] broke chain ancestry", header.Number, hash[:4])
+ break
+ }
// Queue the header for body retrieval
inserts = append(inserts, header)
q.headerPool[hash] = header
q.headerQueue.Push(header, -float32(header.Number.Uint64()))
+ q.headerHead = hash
+ from++
}
return inserts
}