Edit me

[TOC]

在5,6,9中我们描述了tx命令和bpRequester类的代码部分,发现有一个问题,就是账单部分是从内存池中打包的,那么它是如何跑到block区块中去的呢?这里就需要共识模块出马了。

共识模块启动

Angine中几乎所有的模块都是在函数assembleStateMachine中创建的,这是个非常关键的函数,需要注意:

consensusState := consensus.NewConsensusState(ang.logger, conf, stateM, blockStore, mem)
consensusState.SetPrivValidator(ang.privValidator)
consensusReactor := consensus.NewConsensusReactor(ang.logger, consensusState, fastSync)
consensusState.BindReactor(consensusReactor)

创建共识模块,并且绑定一个反射器。反射器这里我们下面再分析,先看看创建部分做了什么工作。 设置了三个回调:

// set function defaults (may be overwritten before calling Start)
cs.decideProposal = cs.defaultDecideProposal
cs.doPrevote = cs.defaultDoPrevote
cs.setProposal = cs.defaultSetProposal

第一个回调就是负责获取账单的:

func (cs *ConsensusState) defaultDecideProposal(height, round agtypes.INT) {
   var block *agtypes.BlockCache
   var blockParts *agtypes.PartSet

   // Decide on block
   if cs.LockedBlock != nil {
      // If we're locked onto a block, just choose that.
      block, blockParts = cs.LockedBlock, cs.LockedBlockParts
   } else {
      // Create a new proposal block from state/txs from the mempool.
      block, blockParts = cs.createProposalBlock()
      if block == nil { // on error
         return
      }
   }

cs.createProposalBlock()就会调用我们在内存池中设置的函数: /home/pct/go/src/github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/consensus/state.go

// Mempool validated transactionsif
var txs agtypes.Txs
if cs.Height == 1 {
   var err error
   txs, err = cs.genInitAllocateTxs()
   if err != nil {
      PanicCrisis(err)
   }
} else {
   txs = cs.mempool.Reap(cs.config.GetInt("block_max_txs"))
}

从内存池获取账单信息: /home/pct/go/src/github.com/Baptist-Publication/chorus/vendor/github.com/Baptist-Publication/angine/mempool/mempool.go

// Get the valid transactions remaining
// If maxTxs is -1, there is no cap on returned transactions.
func (mem *Mempool) Reap(maxTxs int) []agtypes.Tx {
   mem.Lock()
   txs := mem.collectTxs(maxTxs)
   mem.Unlock()
   return txs
}

共识模块的广播机制

Tags: