[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这个类的作用是什么。