Fabric 架构演变之路
Hyperledger Fabric 是目前主流的开源联盟链产品之一,自 2016 年 5 月 12 日开辟代码仓库之日起,已有快 3 年的时间了,产品趋于稳定,功能也越来越完善,正在适配不同业务场景下的需求。
纵观 Fabric 的发布历程,在 v0.6.1-preview 版本至 v1.0.0 的版本迁移过程中架构发生了明显的变化,在 v1.0.0 之后每个小版本中加入了一些新的 feature,来支持不同的业务场景以及完善相应的功能。接下来从个人角度来谈谈 Fabric 架构变迁过程中的一点思考。
Fabric v0.6
v0.6 版本的技术架构在整个发展过程中停留的时间较短,相对目前 v1.x 版本来说,不太稳定,适合做 poc 阶段的测试。
下图是 Fabric v0.6 版本的架构图
在 v0.6 版本中,主要分为 Membership、Consensus、Chaincode、Ledger、P2P、Event Stream 等核心模块。
Membership:负责签发相应的 E-cert、T-cert、TLS-cert 等证书。
Consensus:负责整个区块链的共识,统一交易顺序,保证区块链的一致性。
Chaincode:即链码(Fabric 中的智能合约),用于执行区块链网络中的交易。
Ledger:用于存储 Transaction log 以及交易中的 Key-Value。
P2P:基于 Google 的 Grpc 框架的底层网络通信层。
Event Stream:事件订阅发布组建,用于接收交易及区块事件。
在 Fabric v0.6 中采用的共识算法是 PBFT 算法(Practical Byzantine Fault Tolerance),可以在信任程度较低的场景下避免拜占庭问题。但是由于算法本身特性限制,n>=3f+1,才能容忍一个拜占庭节点,因此在 v0.6 版本下,vp 节点数量至少是 4 个。在 v0.6 版本中,节点角色分为 VP(Validating Peer)、NVP(None validating Peer)以及用于签发证书的 Membership 节点 3 种。当然 Fabric 从第一个版本 v0.6.0-preview 开始就采用基于 docker 的运行时环境,为部署减少了许多麻烦,屏蔽了操作系统的差异。当然最主要的一点也许是由于 Chaincode 的设计机制导致的,整套生产环境的链码的部署和运行都是基于 docker 的,也许是出于 docker 稳定以及相对安全的运行环境的考量。Fabric 的智能合约设计理论上可以支持任何开发语言,只要实现了相应的接口。因为它是基于 Peer 节点和链码容器的一个双向通信完成相应的交互的。
下图是一张 Fabric v0.6 版本的网络拓扑图
在这张图中包含了 VP 和 NVP 2 种角色,NVP 在这里会分担 VP 的部分工作,接收来自客户端发过来的交易进行校验同时将交易请求转发至共识节点 VP,由 VP 节点进行真正的共识,将交易写入区块。在这里 NVP 可以分担共识节点 VP 的处理交易的压力,可以提升共识的性能。
下图为 Fabric v0.6 的交易流程图
应用程序需要先向 Membership 申请 E-cert,通过 E-cert 去申请 T-cert,由 T-cert 对应的私钥进行签名客户端交易发送至 VP 节点进行三阶段共识,完成之后各个节点会通过 Chaincode 按顺序执行区块中的交易,并更新账本。
小结
Fabric v0.6 版本可能由于 1.0 架构重构的原因,没有继续维护推进,但是相对于 1.0 版本的架构来说,这种设计来说,区块链角色相对对称,相对于 1.0-1.4 版本来说,不存在中心化的 Kafka 的存在,在实际场景中拥有更合理对等的节点设计。
Fabric v1.x
Fabric 在 1.0 版本的时候,架构进行了重构,相比于 v0.6 版本来说,有了颠覆性的变革,功能模块进行了结偶,具有了更好的可伸缩性、性能,进行了 channel 级别的安全隔离,共识算法可插拔,具备了更高的可操作性,具备了更丰富的功能,给开发者更好的体验,v0.6 版本中的 Membership 也升级为了一个独立的 Fabric CA 项目。
Fabric v1.x 版本中,对节点进行了功能的拆分,明确了各个节点的指责,将背书的信任假设和排序的信任假设进行了拆分。变动最大的地方在于,在共识流程中将交易的执行进行了提前,由 Endorser 节点进行模拟执行,并进行背书,排序节点 Orderer 会对所有的交易进行统一的打包排序,将其分发给 Committer 节点。这种设计的优势在于可以将前后无关联的交易以及不同 Channel 中的交易进行并行执行,提高交易的执行速度。在 v0.6 版本中是无法做到并行执行的,0.6 中是统一进行排序打包,然后按序执行交易,即使交易前后是无关的。下图也很好地体现了 Fabric v1.x 中的一个网络拓扑。
下图是 Fabric v1.x 版本的架构图
在 v1.x 版本中,主要分为 Fabric CA、Endorser、Committer、Orderer、Application 等角色。
Fabric CA:负责维护整个 Fabric 网络中的证书,主要包括签发、吊销、续签证书等操作。
Endorser:负责对客户端发过来的交易提案进行背书。
Comitter:负责对区块进行有效性校验并将区块写入账本。
Orderer:负责对所有的交易进行全局唯一的排序打包工作。
Application:用于发送交易提案,收集响应,封装交易发送至 Orderer 排序服务节点。
在 1.0 及以后的版本中,客户端应用会先向 Fabric CA 申请用户所需要的 Fabric 中的准入证书,用于签名提案以及交易,然后由客户端(Application)端生成一个提案(Proposal)(一般应用程序会借助于目前 Fabric 提供的一系列 SDK 生成 Proposal)发送至背书节点进行模拟执行并进行背书,背书节点 Endorser 会进行相应的校验,然后将提案交由对应的链码 Chaincode 进行模拟执行,之后背书节点 Endorser 会对执行结果进行背书,将背书的 Response 返回至客户端程序 Application,随之,客户端程收集到符合背书策略的提案响应(Proposal Response)之后,将其封装成一个交易 Transaction,调用排序节点 Orderer 的 Broadcast 接口,进行发送交易至 Orderer,在 v1.0-v1.4 版本中,生产环境只有基于分布式消息队列 Kafka 的排序打包方式,Orderer 作为生产者将交易统一发送至每个通道 Channel 对应的 Topic 的 Partition 当中进行全局统一地排序,同时每个排序节点基于同样的切块规则从 Kafka 中将区块切下推送 Deliver 至与之连接的 Leader Peer(在网络环境良好的情况下,每个组织只有一个 leader),Leader Peer 收到区块后,会将区块通过 Gossip 协议广播至组织内其余节点。每个 Committer 在收到区块之后会对区块进行校验,包括签名、背书策略以及读写集的校验,在校验无误的情况下进行 commit,提交到账本,同时更新世界状态,同时订阅了相应事件的应用程序会收到来自 Event Hub 的消息通知。
下图是一个 Fabric v1.x 的简化版本的交易流程。
此外,在 v1.0 之后,Fabric 强调了组织的概念,在 Peer 节点的层级上,每个组织需要配置一个或者多个 Anchor Peer 节点,来代表组织在整个区块链网络启始之处与别的组织交换节点信息,使得每个节点都能够掌握整个网络的节点信息。
同时,在 v1.0 之后,Fabric 加入了多通道技术(Muti-channel),使得一个 Fabric 网络中能够运行多个账本,每个通道间的逻辑相互隔离不受影响,如下图所示,每种颜色的线条代表一个逻辑上的通道,每个 Peer 节点可以加入不同的通道,每个通道都拥有独立的账本、世界状态、链码以及 Kafka 中的 Topic,通道间消息是隔离的,互不影响的。
在 Fabricv1.x 中,多通道技术是用于在业务逻辑层面做的一个全局的,用于隔离不同业务的通道,使得不同业务的交易存储在不同的通道对应的节点中,通道技术的实现主要在 Orderer 中实现,Orderer 对来自不同通道的交易做区分,同时在 Peer 节点中会采用 MSP 对不同通道的消息做校验,用于判断消息是否属于某个通道,通过 Orderer 以及 Peer 相结合,形成一个逻辑上的通道技术。
在背书和提交校验阶段,Fabric 提出了 2 个系统链码,ESCC 和 VSCC:
- ESCC:用于为链码执行结果进行背书。
- VSCC:用于对接收到的区块中的交易进行校验。
在存储方面,v1.0 也进行了优化,存储的设计分为 2 个部分,一个部分是区块的存储,采用的是 File System 即传统的文件系统,这里设计成采用文件存储的原因在于:区块链中的区块是不断向后追加的,即不断 append 的,不存在随机写的情况,如果采用 Key-Value 数据库可能会存在数据压缩或者相关的索引算法的消耗,在这种场景下,File System 会优于 K-V 数据库,因此不管是 Orderer 还是 Peer,对于区块存储部分,均采用 File System 进行存储,对于 Block 的索引,则采用 Level DB 进行存储维护,会根据 BlockHash、BlockNumber、TxId 等作为 Key 进行存储,而 Value 则是区块或者交易所在的 Segment 号+offset(偏移),用于快速根据 Key 来定位所需要的区块或者交易。
此外,对于世界状态的存储,这里指 State DB,在 v1.0 以后可以用 Level DB 或者 Couch DB 进行存储,根据存储的数据的复杂程度,以及链码的业务逻辑可以选择不同的数据库,比如需要针对 Json 数据进行索引则可以采用 Couch DB 来进行存储,如果是普通的 Key-Value 则可以采用 Level DB 进行存储。
下图是 Fabric v1.0 以后的存储的设计图。
Fabric v1.0 之后的 CA,从 Fabric v0.6 到 v1.0,Fabric CA 是从 Membership 这个模块所衍生出来的,承担整个 Fabric 网络数字证书的签发、续签以及吊销等工作,作为一个独立的服务存在。同时 Fabric CA 支持多级 CA,以保证根 CA 的绝对安全,同时存储部分也是可插拔的,可以选择 MySQL、LDAP、Postgres 等,可以采用 HA Proxy 做负载均衡。
Fabric v1.1
Fabric v1.1 版本主要的新特性包括:
Fabric CA 的 CRL
区块以及交易的事件推送
增加了所有组建间的双向 TLS 通信
Node.js Chaincode 链码的支持
Chaincode API 新增了 creator identity
性能相对 v1.0 有了明显的提升
Fabric v1.2
Fabric v1.2 开始有了比较大的 feature 开始出现:
Private Data Collections:这个特性不得不说在隐私保护上解决了不少项目的痛点,也减少了许多项目为了隐私保护在业务层做的复杂设计。
Service Discovery:服务发现这个特性,使得客户端拥有了更多的灵活性和可操作性,可以动态感知整个 Fabric 网络的变化。
Pluggable endorsement and validation:可插拔的背书及校验机制,采用了 Go Plugin 机制来实现,避免了之前需要重新编译源代码的操作,提升了灵活性。
Fabric v1.3
Fabric v1.3 中,同样增加了十分有用的 feature:
基于 Identity Mixer 的 MSP Implementation:基于零知识证明实现的身份的匿名和不可链接,这个 feature 替代了 v0.6 版本中的 T-cert。
key-level endorsement policies:更细粒度的背书策略,细化到具体的 key-value,更加灵活,不仅限于一个链码程序作背书。
新增 Java Chaincode:至此,v1.3 之后支持了 Go、Node.js、Java 三种 Chaincode,为开发者提供了更多的选择。
Peer channel-based event services:Channel 级别的事件订阅机制,早在 v1.1 版本中已经亮相了,在 v1.3 版本中正式发布,至此,旧的 Event Hub 正式宣告弃用。
Fabric v1.4
Fabric v1.4 是一个里程碑式的版本,是首个 LTS 的版本(Long Term Support 的版本):
可操作性和可维护性的提升:
开放日志级别设置的接口
开放节点健康状态的检查接口
开放节点数据指标的收集接口
改进了 Node SDK 的编程模型,简化开发者的代码复杂度,使得 SDK 更加易用
Private Data 的增强:
对于后续添加的允许访问节点能够获取之前的隐私数据
添加客户端层面的隐私数据的权限控制,不需要添加链码逻辑
总结
对于 Fabric 的架构变迁,从 v0.6 版本到 v1.0 版本有了相对较大的变动,而 v1.0 至 v1.4 之间,也收集了来自业界的不少需求,进行了完善,增加了许多实用的功能,目前 v1.4 版本后续的小迭代会对目前存在的 bug 进行 fix,而新的大 feature 则会在未来的 v2.0 版本中发布,敬请期待吧!
更多区块链技术探讨,添加小助手 18458407117(vx)加入技术交流群与我们共话前沿吧~
版权声明: 本文为 InfoQ 作者【趣链科技】的原创文章。
原文链接:【http://xie.infoq.cn/article/ff7caf8d1fef7993963fbd3db】。文章转载请联系作者。
评论