Edit me

[TOC]

出块条件

如同我们在6中所述,区块代码是函数:

func (bcR *BlockchainReactor) poolRoutine() {
   trySyncTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond)
   statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second)
   switchToConsensusTicker := time.NewTicker(switchToConsensusIntervalSeconds * time.Second)

同步时间是100ms一次,同时会检测下面的条件: 条件一:

first, second := bcR.pool.PeekTwoBlocks()
if first == nil || second == nil {
   // We need both to sync the first block.
   break SYNC_LOOP
}

条件二:

if err := bcR.blockVerifier(pbtypes.BlockID{Hash: first.Hash(), PartsHeader: firstPartsHeader}, first.Header.Height, second.CommitCache()); err != nil {
   bcR.logger.Error("error in validation", zap.String("error", err.Error()))
   bcR.pool.RedoRequest(first.Header.Height)
   break SYNC_LOOP
} else {
   bcR.pool.PopRequest()
   if err := bcR.blockExecuter(first, firstParts, second.CommitCache()); err != nil {
      // TODO This is bad, are we zombie?
      PanicQ(Fmt("Failed to process committed block (%d:%X): %v", first.Header.Height, first.Hash(), err))
   }
}

这里比较奇怪的是,在加入断点时发现代码先执行到条件二,然后又回到条件一,似乎是有地方修改了Pool池:

> github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/blockchain.(*BlockchainReactor).poolRoutine() /home/pct/go/src/github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/blockchain/reactor.go:341 (hits goroutine(124):1 total:1) (PC: 0xc244bb)
Warning: debugging optimized function
   340:                    if err := bcR.blockVerifier(pbtypes.BlockID{Hash: first.Hash(), PartsHeader: firstPartsHeader}, first.Header.Height, second.CommitCache()); err != nil {
=> 341:                        bcR.logger.Error("error in validation", zap.String("error", err.Error()))
   342:                        bcR.pool.RedoRequest(first.Header.Height)
   343:                        break SYNC_LOOP
   344:                    } else {
(dlv) c
> github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/blockchain.(*BlockchainReactor).poolRoutine() /home/pct/go/src/github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/blockchain/reactor.go:332 (hits goroutine(124):1 total:1) (PC: 0xc2580b)
Warning: debugging optimized function
   330:                    if first == nil || second == nil {
   331:                        // We need both to sync the first block.
=> 332:                        break SYNC_LOOP
   333:                    }
   334:                    firstParts := first.MakePartSet(bcR.config.GetInt64("block_part_size")) // TODO: put part size in parts header?

条件一

条件一是从BlockPool变量中取出两个值然后返回,如果没有同时存在两个块,就会退出,不再执行同步操作:

// block requests
requesters map[agtypes.INT]*bpRequester

从变量名称看,这个似乎是请求者,是不是意味着需要两个以上节点才能触发同步操作,我们先看下bpRequester这个类的作用是什么。

Tags: