收获了什么和做了什么是一个重要的议题!
本文章仅是学习交流资料,个人总结。
hyperledger fabric pbft算法架构的简要解析
fabric的共识算法代码全部都在consensus文件夹里,consensus文件夹里主要分为controller,executor,helper,noops,pbft,util文件模块。
其中consensus.go 主要包含了算法插件内部对外部暴露的接口和hyperledger外部对算法内部暴露的接口。
- controller:共识算法模块是可插拔的,在controller里面可以选择具体使用哪种共识算法。目前hyperledger它提供了一个pbft算法和一个比较简单的noops算法。
- executor:executor和helper是两个相互依赖的模块,主要提供了共识算法和外部衔接的一块代码。主要负责事件处理的转接。
- helper:这里面主要包含了对外部接口的一个调用,比如执行处理transaction,stateupdate,持久化一些对象等。
- noops: noops means no operations!(更正)
- pbft: pbft算法,下面会简单的介绍一下pbft算法的调用流程。
- util: 一些交互需要的工具包,最主要的一个实现的功能就是它的消息机制。
下面简要介绍两点,一点pbft算法代码内部从头到尾的一个调用流程,一点是pbft算法内部的事件机制和timeout代码的一个简要解析。
内部调用流程
在engine.go里面有获取一个共识算法plugin
func GetEngine(coord peer.MessageHandlerCoordinator) (peer.Engine, error) {
var err error
engineOnce.Do(func() {
engine = new(EngineImpl)
engine.helper = NewHelper(coord)
engine.consenter = controller.NewConsenter(engine.helper)
engine.helper.setConsenter(engine.consenter)
engine.peerEndpoint, err = coord.GetPeerEndpoint()
engine.consensusFan = util.NewMessageFan()
go func() {
logger.Debug("Starting up message thread for consenter")
// The channel never closes, so this should never break
for msg := range engine.consensusFan.GetOutChannel() {
engine.consenter.RecvMsg(msg.Msg, msg.Sender)
}
}()
})
return engine, err
}
它初始化一个consenter和一个helper,并互相把一个句柄赋值给了对方。这样做的目的,就是为了可以让外部调用内部,内部可以调用外部。
首先看一下它是如何初始化一个共识模块的:
1. 调用controller获取一个plugin,当选择是pbft算法时,它会调用pbft.go 里的 GetPlugin(c consensus.Stack)方法,在pbft.go里面把所有的外部参数读进算法内部。
func New(stack consensus