[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
}