github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/eth/downloader/queue.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  //包含用于收集下载任务和计划的块下载计划程序
    26  //他们井然有序,步履维艰。
    27  
    28  package downloader
    29  
    30  import (
    31  	"errors"
    32  	"fmt"
    33  	"sync"
    34  	"time"
    35  
    36  	"github.com/ethereum/go-ethereum/common"
    37  	"github.com/ethereum/go-ethereum/core/types"
    38  	"github.com/ethereum/go-ethereum/log"
    39  	"github.com/ethereum/go-ethereum/metrics"
    40  	"gopkg.in/karalabe/cookiejar.v2/collections/prque"
    41  )
    42  
    43  var (
    44  blockCacheItems      = 8192             //限制下载前要缓存的最大块数
    45  blockCacheMemory     = 64 * 1024 * 1024 //用于块缓存的最大内存量
    46  blockCacheSizeWeight = 0.1              //乘数,根据过去的块大小近似平均块大小
    47  )
    48  
    49  var (
    50  	errNoFetchesPending = errors.New("no fetches pending")
    51  	errStaleDelivery    = errors.New("stale delivery")
    52  )
    53  
    54  //FetchRequest是当前正在运行的数据检索操作。
    55  type fetchRequest struct {
    56  Peer    *peerConnection //请求发送到的对等机
    57  From    uint64          //[ETH/62]请求的链元素索引(仅用于骨架填充)
    58  Headers []*types.Header //[ETH/62]请求的标题,按请求顺序排序
    59  Time    time.Time       //提出请求的时间
    60  }
    61  
    62  //fetchresult是一个结构,从数据获取程序收集部分结果,直到
    63  //所有未完成的部分都已完成,结果作为一个整体可以处理。
    64  type fetchResult struct {
    65  Pending int         //仍挂起的数据提取数
    66  Hash    common.Hash //阻止重新计算的头的哈希
    67  
    68  	Header       *types.Header
    69  	Uncles       []*types.Header
    70  	Transactions types.Transactions
    71  	Receipts     types.Receipts
    72  }
    73  
    74  //队列表示需要获取或正在获取的哈希
    75  type queue struct {
    76  mode SyncMode //同步模式,用于确定要计划取件的块零件
    77  
    78  //头是“特殊的”,它们批量下载,由一个框架链支持。
    79  headerHead      common.Hash                    //[eth/62]验证顺序的最后一个排队头的哈希
    80  headerTaskPool  map[uint64]*types.Header       //[ETH/62]挂起的头检索任务,将开始索引映射到骨架头
    81  headerTaskQueue *prque.Prque                   //[eth/62]获取填充头的骨架索引的优先级队列
    82  headerPeerMiss  map[string]map[uint64]struct{} //[eth/62]已知不可用的每对等头批的集合
    83  headerPendPool  map[string]*fetchRequest       //[ETH/62]当前挂起的头检索操作
    84  headerResults   []*types.Header                //[ETH/62]结果缓存累积已完成的头段
    85  headerProced    int                            //[ETH/62 ]已从结果中处理的页眉数
    86  headerOffset    uint64                         //[eth/62]结果缓存中第一个头的编号
    87  headerContCh    chan bool                      //[ETH/62]当头下载完成时通知的通道
    88  
    89  //下面的所有数据检索都基于已组装的头链
    90  blockTaskPool  map[common.Hash]*types.Header //[ETH/62]挂起的块(体)检索任务,将哈希映射到头
    91  blockTaskQueue *prque.Prque                  //[eth/62]头的优先级队列,用于获取块(体)
    92  blockPendPool  map[string]*fetchRequest      //[ETH/62]当前正在等待的块(体)检索操作
    93  blockDonePool  map[common.Hash]struct{}      //[ETH/62]完成的块(体)提取集
    94  
    95  receiptTaskPool  map[common.Hash]*types.Header //[ETH/63]挂起的收据检索任务,将哈希映射到标题
    96  receiptTaskQueue *prque.Prque                  //[ETH/63]标题的优先级队列,用于获取收据
    97  receiptPendPool  map[string]*fetchRequest      //[ETH/63]当前正在等待收据检索操作
    98  receiptDonePool  map[common.Hash]struct{}      //[ETH/63]一套完整的收据提取
    99  
   100  resultCache  []*fetchResult     //已下载但尚未传递提取结果
   101  resultOffset uint64             //块链中第一个缓存获取结果的偏移量
   102  resultSize   common.StorageSize //块的近似大小(指数移动平均值)
   103  
   104  	lock   *sync.Mutex
   105  	active *sync.Cond
   106  	closed bool
   107  }
   108  
   109  //new queue为计划块检索创建新的下载队列。
   110  func newQueue() *queue {
   111  	lock := new(sync.Mutex)
   112  	return &queue{
   113  		headerPendPool:   make(map[string]*fetchRequest),
   114  		headerContCh:     make(chan bool),
   115  		blockTaskPool:    make(map[common.Hash]*types.Header),
   116  		blockTaskQueue:   prque.New(),
   117  		blockPendPool:    make(map[string]*fetchRequest),
   118  		blockDonePool:    make(map[common.Hash]struct{}),
   119  		receiptTaskPool:  make(map[common.Hash]*types.Header),
   120  		receiptTaskQueue: prque.New(),
   121  		receiptPendPool:  make(map[string]*fetchRequest),
   122  		receiptDonePool:  make(map[common.Hash]struct{}),
   123  		resultCache:      make([]*fetchResult, blockCacheItems),
   124  		active:           sync.NewCond(lock),
   125  		lock:             lock,
   126  	}
   127  }
   128  
   129  //重置将清除队列内容。
   130  func (q *queue) Reset() {
   131  	q.lock.Lock()
   132  	defer q.lock.Unlock()
   133  
   134  	q.closed = false
   135  	q.mode = FullSync
   136  
   137  	q.headerHead = common.Hash{}
   138  	q.headerPendPool = make(map[string]*fetchRequest)
   139  
   140  	q.blockTaskPool = make(map[common.Hash]*types.Header)
   141  	q.blockTaskQueue.Reset()
   142  	q.blockPendPool = make(map[string]*fetchRequest)
   143  	q.blockDonePool = make(map[common.Hash]struct{})
   144  
   145  	q.receiptTaskPool = make(map[common.Hash]*types.Header)
   146  	q.receiptTaskQueue.Reset()
   147  	q.receiptPendPool = make(map[string]*fetchRequest)
   148  	q.receiptDonePool = make(map[common.Hash]struct{})
   149  
   150  	q.resultCache = make([]*fetchResult, blockCacheItems)
   151  	q.resultOffset = 0
   152  }
   153  
   154  //关闭标记同步结束,取消阻止等待结果。
   155  //即使队列已经关闭,也可以调用它。
   156  func (q *queue) Close() {
   157  	q.lock.Lock()
   158  	q.closed = true
   159  	q.lock.Unlock()
   160  	q.active.Broadcast()
   161  }
   162  
   163  //PendingHeaders检索等待检索的头请求数。
   164  func (q *queue) PendingHeaders() int {
   165  	q.lock.Lock()
   166  	defer q.lock.Unlock()
   167  
   168  	return q.headerTaskQueue.Size()
   169  }
   170  
   171  //PungBug检索待检索的块(体)请求的数量。
   172  func (q *queue) PendingBlocks() int {
   173  	q.lock.Lock()
   174  	defer q.lock.Unlock()
   175  
   176  	return q.blockTaskQueue.Size()
   177  }
   178  
   179  //PendingReceipts检索待检索的块接收数。
   180  func (q *queue) PendingReceipts() int {
   181  	q.lock.Lock()
   182  	defer q.lock.Unlock()
   183  
   184  	return q.receiptTaskQueue.Size()
   185  }
   186  
   187  //InlightHeaders检索当前是否有头提取请求
   188  //在飞行中。
   189  func (q *queue) InFlightHeaders() bool {
   190  	q.lock.Lock()
   191  	defer q.lock.Unlock()
   192  
   193  	return len(q.headerPendPool) > 0
   194  }
   195  
   196  //InlightBlocks检索当前是否存在块提取请求
   197  //飞行。
   198  func (q *queue) InFlightBlocks() bool {
   199  	q.lock.Lock()
   200  	defer q.lock.Unlock()
   201  
   202  	return len(q.blockPendPool) > 0
   203  }
   204  
   205  //航班收据检索当前是否有收据取索请求
   206  //在飞行中。
   207  func (q *queue) InFlightReceipts() bool {
   208  	q.lock.Lock()
   209  	defer q.lock.Unlock()
   210  
   211  	return len(q.receiptPendPool) > 0
   212  }
   213  
   214  //如果队列完全空闲或其中仍有一些数据,则IDLE返回。
   215  func (q *queue) Idle() bool {
   216  	q.lock.Lock()
   217  	defer q.lock.Unlock()
   218  
   219  	queued := q.blockTaskQueue.Size() + q.receiptTaskQueue.Size()
   220  	pending := len(q.blockPendPool) + len(q.receiptPendPool)
   221  	cached := len(q.blockDonePool) + len(q.receiptDonePool)
   222  
   223  	return (queued + pending + cached) == 0
   224  }
   225  
   226  //shouldthrottleBlocks检查是否应限制下载(活动块(正文)
   227  //获取超过块缓存)。
   228  func (q *queue) ShouldThrottleBlocks() bool {
   229  	q.lock.Lock()
   230  	defer q.lock.Unlock()
   231  
   232  	return q.resultSlots(q.blockPendPool, q.blockDonePool) <= 0
   233  }
   234  
   235  //tottleReceipts是否应检查是否应限制下载(活动收据
   236  //获取超过块缓存)。
   237  func (q *queue) ShouldThrottleReceipts() bool {
   238  	q.lock.Lock()
   239  	defer q.lock.Unlock()
   240  
   241  	return q.resultSlots(q.receiptPendPool, q.receiptDonePool) <= 0
   242  }
   243  
   244  //resultslots计算可用于请求的结果槽数
   245  //同时遵守项目和结果的内存限制
   246  //隐藏物。
   247  func (q *queue) resultSlots(pendPool map[string]*fetchRequest, donePool map[common.Hash]struct{}) int {
   248  //计算内存限制限制的最大长度
   249  	limit := len(q.resultCache)
   250  	if common.StorageSize(len(q.resultCache))*q.resultSize > common.StorageSize(blockCacheMemory) {
   251  		limit = int((common.StorageSize(blockCacheMemory) + q.resultSize - 1) / q.resultSize)
   252  	}
   253  //计算已完成的插槽数
   254  	finished := 0
   255  	for _, result := range q.resultCache[:limit] {
   256  		if result == nil {
   257  			break
   258  		}
   259  		if _, ok := donePool[result.Hash]; ok {
   260  			finished++
   261  		}
   262  	}
   263  //计算当前下载的插槽数
   264  	pending := 0
   265  	for _, request := range pendPool {
   266  		for _, header := range request.Headers {
   267  			if header.Number.Uint64() < q.resultOffset+uint64(limit) {
   268  				pending++
   269  			}
   270  		}
   271  	}
   272  //返回空闲插槽进行分发
   273  	return limit - finished - pending
   274  }
   275  
   276  //TraceSkelon将一批报头检索任务添加到队列中以填充
   277  //找到一个已经检索到的头部骨架。
   278  func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) {
   279  	q.lock.Lock()
   280  	defer q.lock.Unlock()
   281  
   282  //无法进行骨架检索,如果进行,则很难失败(巨大的实现错误)
   283  	if q.headerResults != nil {
   284  		panic("skeleton assembly already in progress")
   285  	}
   286  //为骨架程序集安排所有头检索任务
   287  	q.headerTaskPool = make(map[uint64]*types.Header)
   288  	q.headerTaskQueue = prque.New()
   289  q.headerPeerMiss = make(map[string]map[uint64]struct{}) //重置可用性以更正无效的链
   290  	q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch)
   291  	q.headerProced = 0
   292  	q.headerOffset = from
   293  	q.headerContCh = make(chan bool, 1)
   294  
   295  	for i, header := range skeleton {
   296  		index := from + uint64(i*MaxHeaderFetch)
   297  
   298  		q.headerTaskPool[index] = header
   299  		q.headerTaskQueue.Push(index, -float32(index))
   300  	}
   301  }
   302  
   303  //RetrieveHeaders根据调度的
   304  //骨骼。
   305  func (q *queue) RetrieveHeaders() ([]*types.Header, int) {
   306  	q.lock.Lock()
   307  	defer q.lock.Unlock()
   308  
   309  	headers, proced := q.headerResults, q.headerProced
   310  	q.headerResults, q.headerProced = nil, 0
   311  
   312  	return headers, proced
   313  }
   314  
   315  //schedule为下载队列添加一组头以便进行调度,返回
   316  //遇到新邮件头。
   317  func (q *queue) Schedule(headers []*types.Header, from uint64) []*types.Header {
   318  	q.lock.Lock()
   319  	defer q.lock.Unlock()
   320  
   321  //插入按包含的块编号排序的所有标题
   322  	inserts := make([]*types.Header, 0, len(headers))
   323  	for _, header := range headers {
   324  //确保连锁订单始终得到遵守和保存
   325  		hash := header.Hash()
   326  		if header.Number == nil || header.Number.Uint64() != from {
   327  			log.Warn("Header broke chain ordering", "number", header.Number, "hash", hash, "expected", from)
   328  			break
   329  		}
   330  		if q.headerHead != (common.Hash{}) && q.headerHead != header.ParentHash {
   331  			log.Warn("Header broke chain ancestry", "number", header.Number, "hash", hash)
   332  			break
   333  		}
   334  //确保没有执行重复的请求
   335  		if _, ok := q.blockTaskPool[hash]; ok {
   336  			log.Warn("Header  already scheduled for block fetch", "number", header.Number, "hash", hash)
   337  			continue
   338  		}
   339  		if _, ok := q.receiptTaskPool[hash]; ok {
   340  			log.Warn("Header already scheduled for receipt fetch", "number", header.Number, "hash", hash)
   341  			continue
   342  		}
   343  //将标题排队以进行内容检索
   344  		q.blockTaskPool[hash] = header
   345  		q.blockTaskQueue.Push(header, -float32(header.Number.Uint64()))
   346  
   347  		if q.mode == FastSync {
   348  			q.receiptTaskPool[hash] = header
   349  			q.receiptTaskQueue.Push(header, -float32(header.Number.Uint64()))
   350  		}
   351  		inserts = append(inserts, header)
   352  		q.headerHead = hash
   353  		from++
   354  	}
   355  	return inserts
   356  }
   357  
   358  //结果从中检索并永久删除一批提取结果
   359  //高速缓存。如果队列已关闭,则结果切片将为空。
   360  func (q *queue) Results(block bool) []*fetchResult {
   361  	q.lock.Lock()
   362  	defer q.lock.Unlock()
   363  
   364  //统计可供处理的项目数
   365  	nproc := q.countProcessableItems()
   366  	for nproc == 0 && !q.closed {
   367  		if !block {
   368  			return nil
   369  		}
   370  		q.active.Wait()
   371  		nproc = q.countProcessableItems()
   372  	}
   373  //因为我们有一个批量限制,所以不要在“悬空”的记忆中多拉一些。
   374  	if nproc > maxResultsProcess {
   375  		nproc = maxResultsProcess
   376  	}
   377  	results := make([]*fetchResult, nproc)
   378  	copy(results, q.resultCache[:nproc])
   379  	if len(results) > 0 {
   380  //将结果标记为已完成,然后将其从缓存中删除。
   381  		for _, result := range results {
   382  			hash := result.Header.Hash()
   383  			delete(q.blockDonePool, hash)
   384  			delete(q.receiptDonePool, hash)
   385  		}
   386  //从缓存中删除结果并清除尾部。
   387  		copy(q.resultCache, q.resultCache[nproc:])
   388  		for i := len(q.resultCache) - nproc; i < len(q.resultCache); i++ {
   389  			q.resultCache[i] = nil
   390  		}
   391  //前进第一个缓存项的预期块号。
   392  		q.resultOffset += uint64(nproc)
   393  
   394  //重新计算结果项权重以防止内存耗尽
   395  		for _, result := range results {
   396  			size := result.Header.Size()
   397  			for _, uncle := range result.Uncles {
   398  				size += uncle.Size()
   399  			}
   400  			for _, receipt := range result.Receipts {
   401  				size += receipt.Size()
   402  			}
   403  			for _, tx := range result.Transactions {
   404  				size += tx.Size()
   405  			}
   406  			q.resultSize = common.StorageSize(blockCacheSizeWeight)*size + (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize
   407  		}
   408  	}
   409  	return results
   410  }
   411  
   412  //CountProcessableItems统计可处理的项。
   413  func (q *queue) countProcessableItems() int {
   414  	for i, result := range q.resultCache {
   415  		if result == nil || result.Pending > 0 {
   416  			return i
   417  		}
   418  	}
   419  	return len(q.resultCache)
   420  }
   421  
   422  //ReserveHeaders为给定的对等端保留一组头,跳过任何
   423  //以前失败的批。
   424  func (q *queue) ReserveHeaders(p *peerConnection, count int) *fetchRequest {
   425  	q.lock.Lock()
   426  	defer q.lock.Unlock()
   427  
   428  //如果对方已经下载了内容,则短路(请检查是否正常)
   429  //未损坏状态)
   430  	if _, ok := q.headerPendPool[p.id]; ok {
   431  		return nil
   432  	}
   433  //检索一批哈希,跳过以前失败的哈希
   434  	send, skip := uint64(0), []uint64{}
   435  	for send == 0 && !q.headerTaskQueue.Empty() {
   436  		from, _ := q.headerTaskQueue.Pop()
   437  		if q.headerPeerMiss[p.id] != nil {
   438  			if _, ok := q.headerPeerMiss[p.id][from.(uint64)]; ok {
   439  				skip = append(skip, from.(uint64))
   440  				continue
   441  			}
   442  		}
   443  		send = from.(uint64)
   444  	}
   445  //将所有跳过的批合并回
   446  	for _, from := range skip {
   447  		q.headerTaskQueue.Push(from, -float32(from))
   448  	}
   449  //汇编并返回块下载请求
   450  	if send == 0 {
   451  		return nil
   452  	}
   453  	request := &fetchRequest{
   454  		Peer: p,
   455  		From: send,
   456  		Time: time.Now(),
   457  	}
   458  	q.headerPendPool[p.id] = request
   459  	return request
   460  }
   461  
   462  //ReserveBodies为给定的对等端保留一组正文提取,跳过任何
   463  //以前下载失败。除了下一批需要的回迁之外,它还
   464  //返回一个标志,指示是否已将空块排队以进行处理。
   465  func (q *queue) ReserveBodies(p *peerConnection, count int) (*fetchRequest, bool, error) {
   466  	isNoop := func(header *types.Header) bool {
   467  		return header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash
   468  	}
   469  	q.lock.Lock()
   470  	defer q.lock.Unlock()
   471  
   472  	return q.reserveHeaders(p, count, q.blockTaskPool, q.blockTaskQueue, q.blockPendPool, q.blockDonePool, isNoop)
   473  }
   474  
   475  //ReserveReceipts为给定的对等方保留一组收据提取,跳过
   476  //任何以前失败的下载。除了下一批需要的回迁之外,它
   477  //还返回一个标志,指示是否已将空收据排队,需要导入。
   478  func (q *queue) ReserveReceipts(p *peerConnection, count int) (*fetchRequest, bool, error) {
   479  	isNoop := func(header *types.Header) bool {
   480  		return header.ReceiptHash == types.EmptyRootHash
   481  	}
   482  	q.lock.Lock()
   483  	defer q.lock.Unlock()
   484  
   485  	return q.reserveHeaders(p, count, q.receiptTaskPool, q.receiptTaskQueue, q.receiptPendPool, q.receiptDonePool, isNoop)
   486  }
   487  
   488  //ReserveHeaders为给定的对等端保留一组数据下载操作,
   489  //跳过任何以前失败的。此方法是使用的通用版本
   490  //通过单独的特殊预订功能。
   491  //
   492  //注意,此方法预期队列锁已被保存用于写入。这个
   493  //此处未获取锁的原因是参数已经需要
   494  //要访问队列,因此它们无论如何都需要一个锁。
   495  func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque,
   496  	pendPool map[string]*fetchRequest, donePool map[common.Hash]struct{}, isNoop func(*types.Header) bool) (*fetchRequest, bool, error) {
   497  //如果池已耗尽或对等机已耗尽,则短路
   498  //正在下载某些内容(健全性检查不到损坏状态)
   499  	if taskQueue.Empty() {
   500  		return nil, false, nil
   501  	}
   502  	if _, ok := pendPool[p.id]; ok {
   503  		return nil, false, nil
   504  	}
   505  //计算我们可能获取的项目的上限(即限制)
   506  	space := q.resultSlots(pendPool, donePool)
   507  
   508  //检索一批任务,跳过以前失败的任务
   509  	send := make([]*types.Header, 0, count)
   510  	skip := make([]*types.Header, 0)
   511  
   512  	progress := false
   513  	for proc := 0; proc < space && len(send) < count && !taskQueue.Empty(); proc++ {
   514  		header := taskQueue.PopItem().(*types.Header)
   515  		hash := header.Hash()
   516  
   517  //如果我们是第一个请求此任务的人,请初始化结果容器
   518  		index := int(header.Number.Int64() - int64(q.resultOffset))
   519  		if index >= len(q.resultCache) || index < 0 {
   520  			common.Report("index allocation went beyond available resultCache space")
   521  			return nil, false, errInvalidChain
   522  		}
   523  		if q.resultCache[index] == nil {
   524  			components := 1
   525  			if q.mode == FastSync {
   526  				components = 2
   527  			}
   528  			q.resultCache[index] = &fetchResult{
   529  				Pending: components,
   530  				Hash:    hash,
   531  				Header:  header,
   532  			}
   533  		}
   534  //如果此提取任务是NOOP,则跳过此提取操作
   535  		if isNoop(header) {
   536  			donePool[hash] = struct{}{}
   537  			delete(taskPool, hash)
   538  
   539  			space, proc = space-1, proc-1
   540  			q.resultCache[index].Pending--
   541  			progress = true
   542  			continue
   543  		}
   544  //否则,除非知道对等端没有数据,否则将添加到检索列表中。
   545  		if p.Lacks(hash) {
   546  			skip = append(skip, header)
   547  		} else {
   548  			send = append(send, header)
   549  		}
   550  	}
   551  //将所有跳过的邮件头合并回
   552  	for _, header := range skip {
   553  		taskQueue.Push(header, -float32(header.Number.Uint64()))
   554  	}
   555  	if progress {
   556  //wake waitresults,resultcache已修改
   557  		q.active.Signal()
   558  	}
   559  //汇编并返回块下载请求
   560  	if len(send) == 0 {
   561  		return nil, progress, nil
   562  	}
   563  	request := &fetchRequest{
   564  		Peer:    p,
   565  		Headers: send,
   566  		Time:    time.Now(),
   567  	}
   568  	pendPool[p.id] = request
   569  
   570  	return request, progress, nil
   571  }
   572  
   573  //CancelHeaders中止提取请求,将所有挂起的骨架索引返回到队列。
   574  func (q *queue) CancelHeaders(request *fetchRequest) {
   575  	q.cancel(request, q.headerTaskQueue, q.headerPendPool)
   576  }
   577  
   578  //取消主体中止主体提取请求,将所有挂起的头返回到
   579  //任务队列。
   580  func (q *queue) CancelBodies(request *fetchRequest) {
   581  	q.cancel(request, q.blockTaskQueue, q.blockPendPool)
   582  }
   583  
   584  //CancelReceipts中止主体提取请求,将所有挂起的头返回到
   585  //任务队列。
   586  func (q *queue) CancelReceipts(request *fetchRequest) {
   587  	q.cancel(request, q.receiptTaskQueue, q.receiptPendPool)
   588  }
   589  
   590  //取消中止提取请求,将所有挂起的哈希返回到任务队列。
   591  func (q *queue) cancel(request *fetchRequest, taskQueue *prque.Prque, pendPool map[string]*fetchRequest) {
   592  	q.lock.Lock()
   593  	defer q.lock.Unlock()
   594  
   595  	if request.From > 0 {
   596  		taskQueue.Push(request.From, -float32(request.From))
   597  	}
   598  	for _, header := range request.Headers {
   599  		taskQueue.Push(header, -float32(header.Number.Uint64()))
   600  	}
   601  	delete(pendPool, request.Peer.id)
   602  }
   603  
   604  //REVOKE取消属于给定对等机的所有挂起请求。这种方法是
   605  //用于在对等机丢弃期间调用以快速重新分配拥有的数据提取
   606  //到其余节点。
   607  func (q *queue) Revoke(peerID string) {
   608  	q.lock.Lock()
   609  	defer q.lock.Unlock()
   610  
   611  	if request, ok := q.blockPendPool[peerID]; ok {
   612  		for _, header := range request.Headers {
   613  			q.blockTaskQueue.Push(header, -float32(header.Number.Uint64()))
   614  		}
   615  		delete(q.blockPendPool, peerID)
   616  	}
   617  	if request, ok := q.receiptPendPool[peerID]; ok {
   618  		for _, header := range request.Headers {
   619  			q.receiptTaskQueue.Push(header, -float32(header.Number.Uint64()))
   620  		}
   621  		delete(q.receiptPendPool, peerID)
   622  	}
   623  }
   624  
   625  //ExpireHeaders检查是否有超过超时允许的飞行请求,
   626  //取消他们并将负责的同僚送回受罚。
   627  func (q *queue) ExpireHeaders(timeout time.Duration) map[string]int {
   628  	q.lock.Lock()
   629  	defer q.lock.Unlock()
   630  
   631  	return q.expire(timeout, q.headerPendPool, q.headerTaskQueue, headerTimeoutMeter)
   632  }
   633  
   634  //ExpireBodies检查超过超时的飞行中块体请求
   635  //津贴,取消他们,并将负责的同龄人送回受罚。
   636  func (q *queue) ExpireBodies(timeout time.Duration) map[string]int {
   637  	q.lock.Lock()
   638  	defer q.lock.Unlock()
   639  
   640  	return q.expire(timeout, q.blockPendPool, q.blockTaskQueue, bodyTimeoutMeter)
   641  }
   642  
   643  //ExpireReceipts检查超过超时的飞行中接收请求
   644  //津贴,取消他们,并将负责的同龄人送回受罚。
   645  func (q *queue) ExpireReceipts(timeout time.Duration) map[string]int {
   646  	q.lock.Lock()
   647  	defer q.lock.Unlock()
   648  
   649  	return q.expire(timeout, q.receiptPendPool, q.receiptTaskQueue, receiptTimeoutMeter)
   650  }
   651  
   652  //Expire是将过期任务从挂起池移回的常规检查。
   653  //在任务池中,返回捕获到过期任务的所有实体。
   654  //
   655  //注意,此方法期望队列锁已经被持有。这个
   656  //此处未获取锁的原因是参数已经需要
   657  //要访问队列,因此它们无论如何都需要一个锁。
   658  func (q *queue) expire(timeout time.Duration, pendPool map[string]*fetchRequest, taskQueue *prque.Prque, timeoutMeter metrics.Meter) map[string]int {
   659  //迭代过期的请求并将每个请求返回到队列
   660  	expiries := make(map[string]int)
   661  	for id, request := range pendPool {
   662  		if time.Since(request.Time) > timeout {
   663  //用超时更新度量
   664  			timeoutMeter.Mark(1)
   665  
   666  //将任何未满足的请求返回池
   667  			if request.From > 0 {
   668  				taskQueue.Push(request.From, -float32(request.From))
   669  			}
   670  			for _, header := range request.Headers {
   671  				taskQueue.Push(header, -float32(header.Number.Uint64()))
   672  			}
   673  //将对等端添加到到期报告中,同时添加失败请求的数量。
   674  			expiries[id] = len(request.Headers)
   675  		}
   676  	}
   677  //从挂起的池中删除过期的请求
   678  	for id := range expiries {
   679  		delete(pendPool, id)
   680  	}
   681  	return expiries
   682  }
   683  
   684  //DeliverHeaders将头检索响应注入头结果中
   685  //隐藏物。此方法要么接受它接收到的所有头,要么不接受任何头。
   686  //如果它们不能正确映射到骨架。
   687  //
   688  //如果头被接受,该方法将尝试传递集合
   689  //准备好的头到处理器以保持管道满。然而它会
   690  //不阻止阻止其他待定的交付。
   691  func (q *queue) DeliverHeaders(id string, headers []*types.Header, headerProcCh chan []*types.Header) (int, error) {
   692  	q.lock.Lock()
   693  	defer q.lock.Unlock()
   694  
   695  //如果从未请求数据,则短路
   696  	request := q.headerPendPool[id]
   697  	if request == nil {
   698  		return 0, errNoFetchesPending
   699  	}
   700  	headerReqTimer.UpdateSince(request.Time)
   701  	delete(q.headerPendPool, id)
   702  
   703  //确保头可以映射到骨架链上
   704  	target := q.headerTaskPool[request.From].Hash()
   705  
   706  	accepted := len(headers) == MaxHeaderFetch
   707  	if accepted {
   708  		if headers[0].Number.Uint64() != request.From {
   709  			log.Trace("First header broke chain ordering", "peer", id, "number", headers[0].Number, "hash", headers[0].Hash(), request.From)
   710  			accepted = false
   711  		} else if headers[len(headers)-1].Hash() != target {
   712  			log.Trace("Last header broke skeleton structure ", "peer", id, "number", headers[len(headers)-1].Number, "hash", headers[len(headers)-1].Hash(), "expected", target)
   713  			accepted = false
   714  		}
   715  	}
   716  	if accepted {
   717  		for i, header := range headers[1:] {
   718  			hash := header.Hash()
   719  			if want := request.From + 1 + uint64(i); header.Number.Uint64() != want {
   720  				log.Warn("Header broke chain ordering", "peer", id, "number", header.Number, "hash", hash, "expected", want)
   721  				accepted = false
   722  				break
   723  			}
   724  			if headers[i].Hash() != header.ParentHash {
   725  				log.Warn("Header broke chain ancestry", "peer", id, "number", header.Number, "hash", hash)
   726  				accepted = false
   727  				break
   728  			}
   729  		}
   730  	}
   731  //如果批头未被接受,则标记为不可用
   732  	if !accepted {
   733  		log.Trace("Skeleton filling not accepted", "peer", id, "from", request.From)
   734  
   735  		miss := q.headerPeerMiss[id]
   736  		if miss == nil {
   737  			q.headerPeerMiss[id] = make(map[uint64]struct{})
   738  			miss = q.headerPeerMiss[id]
   739  		}
   740  		miss[request.From] = struct{}{}
   741  
   742  		q.headerTaskQueue.Push(request.From, -float32(request.From))
   743  		return 0, errors.New("delivery not accepted")
   744  	}
   745  //清除成功的获取并尝试传递任何子结果
   746  	copy(q.headerResults[request.From-q.headerOffset:], headers)
   747  	delete(q.headerTaskPool, request.From)
   748  
   749  	ready := 0
   750  	for q.headerProced+ready < len(q.headerResults) && q.headerResults[q.headerProced+ready] != nil {
   751  		ready += MaxHeaderFetch
   752  	}
   753  	if ready > 0 {
   754  //收割台准备好交付,收集它们并向前推(非阻塞)
   755  		process := make([]*types.Header, ready)
   756  		copy(process, q.headerResults[q.headerProced:q.headerProced+ready])
   757  
   758  		select {
   759  		case headerProcCh <- process:
   760  			log.Trace("Pre-scheduled new headers", "peer", id, "count", len(process), "from", process[0].Number)
   761  			q.headerProced += len(process)
   762  		default:
   763  		}
   764  	}
   765  //检查终止和返回
   766  	if len(q.headerTaskPool) == 0 {
   767  		q.headerContCh <- false
   768  	}
   769  	return len(headers), nil
   770  }
   771  
   772  //DeliverBodies将块体检索响应注入结果队列。
   773  //该方法返回从传递中接受的块体数,以及
   774  //同时唤醒等待数据传递的任何线程。
   775  func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, uncleLists [][]*types.Header) (int, error) {
   776  	q.lock.Lock()
   777  	defer q.lock.Unlock()
   778  
   779  	reconstruct := func(header *types.Header, index int, result *fetchResult) error {
   780  		if types.DeriveSha(types.Transactions(txLists[index])) != header.TxHash || types.CalcUncleHash(uncleLists[index]) != header.UncleHash {
   781  			return errInvalidBody
   782  		}
   783  		result.Transactions = txLists[index]
   784  		result.Uncles = uncleLists[index]
   785  		return nil
   786  	}
   787  	return q.deliver(id, q.blockTaskPool, q.blockTaskQueue, q.blockPendPool, q.blockDonePool, bodyReqTimer, len(txLists), reconstruct)
   788  }
   789  
   790  //DeliverReceipts将收据检索响应插入结果队列。
   791  //该方法返回从传递中接受的事务处理接收数。
   792  //并唤醒等待数据传递的任何线程。
   793  func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt) (int, error) {
   794  	q.lock.Lock()
   795  	defer q.lock.Unlock()
   796  
   797  	reconstruct := func(header *types.Header, index int, result *fetchResult) error {
   798  		if types.DeriveSha(types.Receipts(receiptList[index])) != header.ReceiptHash {
   799  			return errInvalidReceipt
   800  		}
   801  		result.Receipts = receiptList[index]
   802  		return nil
   803  	}
   804  	return q.deliver(id, q.receiptTaskPool, q.receiptTaskQueue, q.receiptPendPool, q.receiptDonePool, receiptReqTimer, len(receiptList), reconstruct)
   805  }
   806  
   807  //传递将数据检索响应注入结果队列。
   808  //
   809  //注意,此方法预期队列锁已被保存用于写入。这个
   810  //此处未获取锁的原因是参数已经需要
   811  //要访问队列,因此它们无论如何都需要一个锁。
   812  func (q *queue) deliver(id string, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque,
   813  	pendPool map[string]*fetchRequest, donePool map[common.Hash]struct{}, reqTimer metrics.Timer,
   814  	results int, reconstruct func(header *types.Header, index int, result *fetchResult) error) (int, error) {
   815  
   816  //如果从未请求数据,则短路
   817  	request := pendPool[id]
   818  	if request == nil {
   819  		return 0, errNoFetchesPending
   820  	}
   821  	reqTimer.UpdateSince(request.Time)
   822  	delete(pendPool, id)
   823  
   824  //如果未检索到数据项,则将其标记为对源对等机不可用
   825  	if results == 0 {
   826  		for _, header := range request.Headers {
   827  			request.Peer.MarkLacking(header.Hash())
   828  		}
   829  	}
   830  //将每个结果与其标题和检索到的数据部分组合在一起
   831  	var (
   832  		accepted int
   833  		failure  error
   834  		useful   bool
   835  	)
   836  	for i, header := range request.Headers {
   837  //如果找不到更多提取结果,则短路程序集
   838  		if i >= results {
   839  			break
   840  		}
   841  //如果内容匹配,则重建下一个结果
   842  		index := int(header.Number.Int64() - int64(q.resultOffset))
   843  		if index >= len(q.resultCache) || index < 0 || q.resultCache[index] == nil {
   844  			failure = errInvalidChain
   845  			break
   846  		}
   847  		if err := reconstruct(header, i, q.resultCache[index]); err != nil {
   848  			failure = err
   849  			break
   850  		}
   851  		hash := header.Hash()
   852  
   853  		donePool[hash] = struct{}{}
   854  		q.resultCache[index].Pending--
   855  		useful = true
   856  		accepted++
   857  
   858  //清除成功的获取
   859  		request.Headers[i] = nil
   860  		delete(taskPool, hash)
   861  	}
   862  //将所有失败或丢失的提取返回到队列
   863  	for _, header := range request.Headers {
   864  		if header != nil {
   865  			taskQueue.Push(header, -float32(header.Number.Uint64()))
   866  		}
   867  	}
   868  //唤醒等待结果
   869  	if accepted > 0 {
   870  		q.active.Signal()
   871  	}
   872  //如果没有一个数据是好的,那就是过时的交付
   873  	switch {
   874  	case failure == nil || failure == errInvalidChain:
   875  		return accepted, failure
   876  	case useful:
   877  		return accepted, fmt.Errorf("partial failure: %v", failure)
   878  	default:
   879  		return accepted, errStaleDelivery
   880  	}
   881  }
   882  
   883  //准备将结果缓存配置为允许接受和缓存入站
   884  //获取结果。
   885  func (q *queue) Prepare(offset uint64, mode SyncMode) {
   886  	q.lock.Lock()
   887  	defer q.lock.Unlock()
   888  
   889  //为同步结果准备队列
   890  	if q.resultOffset < offset {
   891  		q.resultOffset = offset
   892  	}
   893  	q.mode = mode
   894  }