hyperledger fabric PBFT算法简要解析
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也是一种比较简单共识算法
- pbft: pbft算法,下面会简单的介绍一下pbft算法的调用流程。
- util: 一些交互需要的工具包,最主要的一个实现的功能就是它的消息机制。
下面简要介绍两点,一点pbft算法代码内部从头到尾的一个调用流程,一点是pbft算法内部的事件机制和timeout代码的一个简要解析。
内部调用流程
在engine.go里面有获取一个共识算法plugin
func GetEngine(coord peer.MessageHandlerCoordinator) (peer.Engine, error) {var err errorengineOnce.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 breakfor 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.Stack) consensus.Consenter {handle, _, _ := stack.GetNetworkHandles()id, _ := getValidatorID(handle)switch strings.ToLower(config.GetString("general.mode")) {case "batch":return newObcBatch(id, config, stack)default:panic(fmt.Errorf("Invalid PBFT mode: %s", config.GetString("general.mode")))}
}
2. 用方法newObcBatch(id uint64, config *viper.Viper, stack consensus.Stack)初始化一个obcbatch对象。这个batch对象的作用就是用来做request缓存,提高transaction的执行效率,如果每来一个请求就去做一次共识,那代价会很高。缓存存储在batchStore里。3. 在newobcbatch时,会初始化得到一个pbftcore的一个实例,这个是算法的核心模块。并此时会启动一个batchTimer(这个batchTimer是一个计时器,当batchTimer timeout后会触发一个sendbatch操作,这个只有primary节点才会去做)。当然此时会创建一个事件处理机制,这个事件处理机制是各个模块沟通的一个bridge。4. 在初始化pbftcore时,在把所用配置读进的同时,创建了三个timer
instance.newViewTimer = etf.CreateTimer()
instance.vcResendTimer = etf.CreateTimer()
instance.nullRequestTimer = etf.CreateTimer()
- newViewTimer对应于viewChangeTimerEvent{},当这个timer在一定时间没有close时,就会触发一个viewchange事件。
- vcResendTimer对应viewChangeResendTimerEvent,发出viewchange过时时会触发一个将viewchange从新发送。
- nullRequestTimer对应nullRequestEvent,如果主节点长期没有发送preprepare消息,也就是分配了seq的reqBatch。它timeout就认为主节点挂掉了然后发送viewchange消息。
当然理解以上东西需要了解pbft算法的各个具体流程。以上是pbft算法插件的初始化流程, 并讲解了部分初始化我认为比较重要的信息。具体初始化需要看代码了。
算法内部的事件机制
为什么要把事件机制单独提出来,因为要想完全看懂它的调用流程,就必须理解它的事件流。说起来它的事件流真是复杂,我觉得可以不必要这么复杂。
它有两个事件流,一个是在helper里,一个是在batch里。
首先分析一下它的事件流工具,它整个代码都在util包里的events.go,我认为这个设计还是棒棒哒,在我自己的共识算法测试环境里,对它改装了一下,感觉还是不错的。
首先看一下它提供的接口
type Manager interface {Inject(Event) // A temporary interface to allow the event manager thread to skip the queueQueue() chan<- Event // Get a write-only reference to the queue, to submit eventsSetReceiver(Receiver) // Set the target to route events toStart() // Starts the Manager thread TODO, these thread management things should probably go awayHalt() // Stops the Manager thread
}
SetReceiver(Receiver)是一个很重要的接口,决定了这个事件机制的灵活性。考验我表达能力的时候到了~~,一个事件机制必定有一个输入和一个输出,这个SetReceiver(Receiver) interface 方法就决定了事件流的去向。下面是receiver的interface,凡是事件的接受者都必须实现ProcessEvent(e Event) Event方法。batch里面实现了此方法。
type Receiver interface {// ProcessEvent delivers an event to the Receiver, if it returns non-nil, the return is the next processed eventProcessEvent(e Event) Event
}
那对应的输出,Queue() chan<- Event ,它返回一个event channel,你所有的消息尽管往里面发。接收者取决于receiver。
func SendEvent(receiver Receiver, event Event) {next := eventfor {// If an event returns something non-nil, then process it as a new eventnext = receiver.ProcessEvent(next)if next == nil {break}}
}
这段代码是把事件传给receiver处理。举个batch事件流机制的例子。
在external.go里面实现了接收外边request请求的接口。在obcbatch初始化会对其创建并且把event manager复制给externalEventReceiver。因此所有接收到这个manager的消息都会进入到batch里面。
// RecvMsg is called by the stack when a new message is received
func (eer *externalEventReceiver) RecvMsg(ocMsg *pb.Message, senderHandle *pb.PeerID) error {eer.manager.Queue() <- batchMessageEvent{msg: ocMsg,sender: senderHandle,}return nil
}
当接收到一个request时,将batchMessageEvent放到事件流,之后
func (em *managerImpl) eventLoop() {for {select {case next := <-em.events:em.Inject(next)case <-em.exit:logger.Debug("eventLoop told to exit")return}}
}
这个死循环接收到的event 进行了em.Inject(next),并执行
func SendEvent(receiver Receiver, event Event) {next := eventfor {// If an event returns something non-nil, then process it as a new eventnext = receiver.ProcessEvent(next)if next == nil {break}}
}
之后在obcbatch ProcessEvent里执行了这个操作
case batchMessageEvent:ocMsg := etreturn op.processMessage(ocMsg.msg, ocMsg.sender)
这是消息往里抛的过程,同理,消息往外抛,就是算法内部把event抛给外部executor的event manager。
Timer机制
timer机制和event机制有很大关联,time out后,会把事先创建的event塞到eventmanager里的事件流里。
type Timer interface {SoftReset(duration time.Duration, event Event) // start a new countdown, only if one is not already startedReset(duration time.Duration, event Event) // start a new countdown, clear any pending eventsStop() // stop the countdown, clear any pending eventsHalt() // Stops the Timer thread
}
设置time out主要是SoftReset和reset方法。因此在初始化,会把Manager传给Timer。
但这样的事件机制在大数据处理时,可能会出现问题。
hyperledger fabric PBFT算法简要解析相关推荐
- HyperLedger Fabric共识算法
当前在联盟链的应用场景中,使用的共识算法有3种:SOLO.Kafka和PBFT(拜占庭容错). Solo模式 在Hyperledger Fabric中的solo模式的共识算法,是最简单的一种共识算法, ...
- 浅析Hyperledger Fabric共识算法
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 区块链系统是一个分布式架构,交易账本信息由各个节点管理,组成一个庞大的分布式账本.在分布式系统中,各个节点收到的交易信息 ...
- hyperledger fabric 交易结构以及解析
Fabric 1.0源代码分析(43) Tx(Transaction 交易)_yinchengmvp的技术博客_51CTO博客 Hyperledger Fabric的区块结构 交易结构Hyperled ...
- 在 Hyperledger Fabric v1.4 下添加 PBFT 共识算法
在文章的开篇,首先对如下两篇文章的博主表示感谢,感谢他们对学习资源的共享. https://www.yezhem.com/index.php/archives/52/ https://blog.csd ...
- Hyperledger Fabric相关文件解析
1相关文件说明 这一部分涉及相关配置文件的解析, 网络的启动涉及到多个文件,本文按以下顺序进行分析: . ├── base │ ├── docker-compose-base.yaml #1 │ └─ ...
- Fabric学习笔记-PBFT算法
本文介绍了实用拜占庭容错算法(PBFT). Fabric在v0.6中采用的是PBFT算法,在v1.0.0-preview中是SBFT算法,在v1.0.0-release中文档上说PBFT还在开发中,项 ...
- Hyperledger Fabric无排序组织以Raft共识算法启动多个Orderer服务、多组织共同运行维护Orderer服务
前言 在Hyperledger Fabric无系统通道启动及通道的创建和删除中,我们已经完成了以无系统通道的方式启动 Hyperledger Fabric 网络,并将链码安装到指定通道.但目前为止,实 ...
- Hyperledger Fabric 2.0 官方文档中文版 第3章 关键概念
Hyperledger Fabric 2.0 官方文档中文版 第3章 关键概念 总目录 3.关键概念 引言 什么是区块链? 区块链为什么有用? 什么是Hyperledger Fabric? Hyper ...
- (转)HyperLedger Fabric协议规范
HyperLedger Fabric协议规范 协议规范 前言 这份文档是带有权限的区块链的工业界实现的协议规范.它不会详细的解释实现细节,而是描述系统和应用之间的接口和关系. 目标读者 这份规范的目标 ...
- 以太坊和Hyperledger Fabric之间的差异
在这篇文章中,我们将介绍区块链中两个主要平台之间的差异:以太坊和Hyperledger.如果你正在考虑在项目中使用哪一个.这个博客的亮点是希望帮助你做出决定.但在我们详细说明之前,我们先来看一些定义. ...
最新文章
- 堆(heap)与栈(stack)的区别(二)
- eclipse中搭建ssm框架
- 今日头条技术架构到底有多牛?
- 如何成为一名大数据工程师?
- PYTHON自动化Day4-交换变量,字符串方法,拷贝,集合,文件,文件指针
- 世界首个!AI农作物病害检测竞赛火热进行中 | AI Challenger 全球AI挑战赛
- 如果你忘记了DotnetNuke站点的host和admin密码,解决方案
- java 用mysql游标_MySQL游标
- VC第三方界面库xtremetoolkitPro使用说明
- 震旦ad369s_震旦ad369s驱动
- 公众号写作排版指南v2.0(适配Dark Mode)
- 实现表格隔行变色研究
- error obtaining controller instance: failed to create NAT chain
- 大规模知识图谱数据存储实战解析
- 沈向洋回归,从微软独立的小冰要弯道超车了
- 程序员用代码求救 同事“秒懂”
- Rational Rose2007的安装
- Hudi on Flink在顺丰的实践应用.ppt
- Word中插入手写体签名
- OpenCV库中watershed函数(分水岭算法)的详细使用例程
热门文章
- 支持多浏览器的js拖拽 (转domkey0303 的blog)
- instead of触发器实现复杂视图dml和应用逻辑
- 2. 知识图谱-命名实体识别(NER)详解
- CSS3 transform 属性
- ABAP-内表数据下载到CSV格式(原创转载请注明)
- 字符串反转的进一步应用----单词反转
- 利用TreeView控件动态生成无限级树(续:通过绑定动态xml文件)(转)
- DDMF PluginDoctor Mac - 插件分析器音频质量测试
- iOS底层探索之多线程(二)—线程和锁
- 怎样才能打开Tuxera NTFS的主界面?