Edit me

[TOC]

在账单获取章节,我们发现在执行到线程poolRoutine时,账单已经被打包进了BlockPool->bpRequester->BlockCache->Block->Data中了,因此我们需要理清这个数据是什么时候填充的。

类描述

type BlockPool struct {
   BaseService
   startTime time.Time

   mtx sync.Mutex
   // block requests
   requesters map[agtypes.INT]*bpRequester
   height     agtypes.INT // the lowest key in requesters.
   numPending int32       // number of requests pending assignment or block response
   // peers
   peers map[string]*bpPeer

   requestsCh chan<- BlockRequest
   timeoutsCh chan<- string

   logger *zap.Logger
}

BaseService是用来启动服务的,和前面我们描述的几个服务类相似,就不赘述了。 requesters就是我们在11章节中描述的类。 height这个参数含义不明 numPending这个参数后面会有值的判断,似乎是连接最大数 peers节点的一些信息 requestsCh,通信channel,在sendRequest中被调用,未检测到使用。 timeoutsCh,通信channel,在sendTimeout中被调用,未检测到使用。

启动流程

启动:

func (pool *BlockPool) OnStart() error {
   pool.BaseService.OnStart()
   go pool.makeRequestersRoutine()
   pool.startTime = time.Now()
   return nil
}

pool.makeRequestersRoutine()启动自身线程。 自身线程我们关注下面这个函数:

// request for more blocks.
pool.makeNextRequester()

此函数除了request.Start()启动bpRequesters的线程外,还创建了新的request,这个就是我们要找的:

nextHeight := pool.height + agtypes.INT(len(pool.requesters))
request := newBPRequester(pool, nextHeight)

pool.requesters[nextHeight] = request
pool.numPending++

pool.height这个值是启动时设置的,默认是1,那么执行这部分代码就会增加一个requesters到map中,通过打印发现一共添加了300个requesters,然后就不再执行了。

len(pool.requesters): 299
pool.height: 1
nextHeight: 300
numPending: 300

为什么是300个呢,这就会回到上面的pool.makeRequestersRoutine()线程循环体内了:

// Run spawns requesters as needed.
func (pool *BlockPool) makeRequestersRoutine() {
   for {
      if !pool.IsRunning() {
         break
      }
      _, numPending, lenRequesters := pool.GetStatus()
      if numPending >= maxPendingRequests {
         // sleep for a bit.
         time.Sleep(requestIntervalMS * time.Millisecond)
         // check for timed out peers
         pool.removeTimedoutPeers()
      } else if lenRequesters >= maxTotalRequesters {
         // sleep for a bit.
         time.Sleep(requestIntervalMS * time.Millisecond)
         // check for timed out peers
         pool.removeTimedoutPeers()
      } else {
         // request for more blocks.
         pool.makeNextRequester()
      }
   }
}

maxPendingRequests的取值是300,因此如果numPending到300后,就不再添加新的requesters了。开始检测超时节点并清除。

block填充

上面我们只是分析了requesters的创建,那么在创建时的block是怎么填充的呢,在出块时还是通过block来获取数据的。 填充部分参见共识模块章节。

Tags: