fabric学习过程详细记录一
以下阅读笔记来自阅读《深度探索区块链 HYPERLEDGER技术与应用》
以下所有信息,适用于fabric1.0版本
MSP(成员服务提供者,验证签名有效性)
基于MSP身份标识拥有不同类型的MSP主体(MSPPrincipal)。P58
三种类型,有基于MSP角色的验证(member或者admin),基于部门的验证,基于具体的身份证书的验证。
成员认证及身份管理 P67
每个节点都有MSP颁发的证书,证书哈希得到节点标识符 PKI-ID(目前实现是由endpoint直接转换过来)
身份管理模块维护了键值映射表pkiID2Cert,用来获取节点证书和更新节点证书。还内置了MCS模块(MessageCryptoService,翻译为消息加密服务,用于对消息签名和验证,更新证书时验证证书是否有效)。
TLS协议(最重要也最难理解的是TLS握手协议) Transport Layer Security
相关的有SSL协议。记录一个讲SSL协议讲的比较明白的博客
https://blog.csdn.net/u013750244/article/details/98881620
RwSet 读写集 P41
交易号位图 TxValidationFlags P46 用于记录每个交易号的交易验证状态
交易提案:SignedProposal P39 P52
交易提案消息的结构由ProposalBytes(或称为Proposal,提案主要内容)和Signatue(签名)组成。其中Proposal由头部,负载和可选扩展三部分组成。
提案响应:ProposalResponse P41 P54
提案响应中,除了有基本的消息版本号,时间戳,背书是否成功标志,最重要的有ProposalResponsePayload(提案响应负载)和Endorsement(背书节点身份以及签名)
构造交易请求: Envelope P43
背书交易:交易信息的负载Transcation包含多个TranscationAction(即一个TranscationAction数组,以此来适应多个动作)。P55
TranscationAction中的负载为ChaincodeActionPayload消息 P56
ChaincodeActionPayload包含chaincode_proposal_payload以及ChaincodeEndorsedAction(应用于账本的动作列表,承载有关于具体提案的背书信息) P56
Gossip服务模块:peer节点从该模块接收区块
基于Gossip的P2P数据转发 P65
VSCC背书策略
在背书和提交校验阶段,Fabric提出了2个系统链码,ESCC和VSCC:
ESCC(交易背书系统链码):用于为链码执行结果进行背书。
VSCC:用于对接收到的区块中的交易进行背书策略校验
在fabric1.2中。Escc和vscc被独立了出来(不能在core/scc目录下被找到了),提供了签名(验证策略)和state相关的依赖项,可以自己实现接口,编译成so文件引用。
MVCC(多版本并行控制)状态检查 (由peer节点检查,只校验读数据,写和删除数据为批量操作,保证状态数据库的一致和提升效率)
无效交易仍旧会被记录到区块,但不会更新到状态数据库(后续版本会实现账本精简,过滤无效交易)
信封消息由消息负载和签名组成 P49
消息负载中有头部hader和数据data
头部中有通道头和签名头
数据字段的类型由头部指定(HeaderType)
对于配置信息交易,没有依赖项目。故每个配置交易使用全量数据,而非增量数据。这个措施也更容易引导新的peer节点或者排序节点,也便于未来的裁剪工作。
配置交易信封的头部类型为 CONFIGURATION_TRANSCATION,负载数据为ConfigurationEnvelope
配置信息的信封中嵌入一系列的SignedConfigurationItems,它包含重复的信封消息,头部类型为CONFIGURATION_ITEM,负载数据为ConfigurationItem
当信封data中携带链码相关消息时,使用信封的类型为ENDORSER_TRANSCATION。
ACL检查(背书节点检查客户端提案的交易是否被允许)P53
策略管理,权限管理的一种方法,基于策略。有交易背书策略,链码实例化策略和通道管理策略等。 P56
策略定义为由类型和内容组成的结构体。
策略有两种类型,SignaturePolicy(基于签名验证)和ImplicitMetaPolicy(隐含元策略,递归策略的定义方法,适用于通道管理策略)
基于Gossip的P2P数据分发
超级账本的Gossip实现方式是每次收到数据包后,随机选择k个邻接节点进行转发。
优点:提高效率(相比于泛洪,是显然的),扩展性(转发概率基于本地信息,与全网节点数量无关,扩展节点对于系统而言比较稳定),适应性(Gossip协议自我调整网络拓扑结构,适应网络节点变化),优雅降级(协议正确工作概率不会因为错误节点超过f值而迅速降低)。
主节点选举(leader election)P68
主节点通过deliver()连接排序节点,在自己的组织中广播收到的批量区块数据。
此功能在Gossip层实现。而且假设在某时间段内存在多个主节点,防止拜占庭行为发生(为什么?但最终在一个组织中,通过选举,只存在一个主节点)
LeadershipMessage有两种类型,主节点选举消息proposal,声明成为主节点消息declaration
一次主节点选举有效时间LeaderAliveThreshold是10s。意味着主节点是动态变化的。当然了,因为根据PKI-ID来排序主节点优先级,在网络节点成员以及网络通道状况比较稳定的情况下,主节点一般是不变的。
基于反熵(anti-entropy)的状态同步过程,在不同节点间同步状态 P66 P69
网络中的节点会周期性交流确保自己的账本是最新的,若不是,则会广播请求GossipMessage_StateRequest.
其他拥有缺失区块的节点会广播GossipMessage_StateResponse.
提供缺失块的过程使用了直接消息(directMessage)(什么是直接消息?)
PayloadsBuffer数据结构用来缓存这些收到的缺失区块。
更新状态数据的过程有两种方式,一个就是直接消息,另一个就是由主节点广播的GossipMessage_DataMsg
节点启动及成员管理P67
配置文件Core.yaml中字段peer.gossip.bootstrap=启动集合BootstrapSet
节点启动给启动集合中的节点发送MembershipRequest消息
MembershipRequest消息包含AliveMessage和已知存活节点列表(其中提到endpoint=host+”:”+port)
AliveMessage在启动的一段时间内会包含节点证书,用于验证签名。
节点的AliveMessage消息会周期性广播,来保持自己在网络中其他节点视角中为存活状态。
多通道的支持 P70
消息的验证策略 P71
通过gossip协议转发的消息都会声明一些节点的信息(例如PKI-ID,签名,能通过证书验证)。点对点传播的消息则不需要签名,不会通过gossip转发。
唯一不使用点对点传播并且不需要节点签名的消息是账本数据区块,它由排序服务签名。
Peer节点收到账本数据区块消息后,会对排序服务的签名进行验证。这里有许多不同的验证策略
超级账本声明的一个内部消息存储接口 MessageStore
其中有一个消息策略验证函数MessageReplacingPolicy
不同类型的内部消息具有不同的验证策略 可参考表4-1
由于gossip协议转发的消息种类很多,所以有实现了一个消息的多路分用接口ChannelDeMultiplexer
在这个接口中,定义了一个channel数组。
Channel这个数据结构中包含判断策略pred和缓存通道ch。通过判断如果被认为有用的消息就存到缓存中。
这个pred策略 函数类型为MessageAcceptor ,即消息过滤器
Gossip实现了多种类型的消息过滤器。多种消息过滤器分层组合成类似漏洞的结构,实现多路分用。定义了channel数组,不同channel之间采用的pred不同,所以不同channel可能存在相同的消息。
对于需要广播的消息,还实现了消息分区,同一个消息经过分区过滤器后,只会出现在一个列表中。这是和多路分用过滤器不同的地方。
超级账本存储包含以下几个元素(前四个使用数据库,后一个采用日志)
账本编号 idStore 存储 chainID
状态数据 stateDB 存储 world state
历史数据 historyDB 存储key的版本变化
区块索引 blockIndex 存储block索引
账本数据 基于文件系统
背书节点模拟执行会生成读写集。读集包含键的版本号,写集包含键的最新值以及是否要删除的标记。
以下就是一个读写集的例子
提交节点的验证是对读集进行验证,根据写集更新状态数据。
范围查询?若有范围查询,读写集中会包含query-info
以及,检查query-info可以防止幻影项(?)幻影保护只实现了范围查询。其他查询仍旧有幻影风险。
基于文件系统的区块存储主要实现了账本存储管理和索引管理两大功能接口。
区块存储所有操作通过区块文件管理器(blockfileMgr)实现,有以下三类功能,账本数据存储管理,检查点管理和索引管理。
写入区块文件的数据有两部分,一个是区块大小,一个是区块数据。在读取的时候,也是先读取区块大小,再读取区块文件。
索引有多种类型,建立哪些索引是可选的,默认全部建立。排序服务节点则只会建立区块编号索引。
构建索引的途径有两种,提交区块和同步索引(在创建区块文件管理器的时候进行)
索引的同步过程 P86
状态数据库本质上是交易日志的的索引视图,随时可以根据区块链生成。其在peer节点启动时被构建。构建完成后才能接受新交易。
读取状态数据时返回的是某个时刻最新版本的数据,并不能指定版本。返回的数据VersionedValue包含版本号version 和数据value。其中版本号由交易高度(区块编号组合交易编号,BlockNum和TxNum)表示。
Peer节点在区块提交到账本前会进行基于状态的区块验证。目前区块分为配置交易区块和背书交易区块。配置区块验证尚未实现,总是为成功。
验证通过的交易的读写集会放到UpdateBatch中。若存在同区块交易会读取UpdateBatch中的记录,也将导致验证失败。
验证分为基于版本的验证和基于范围查询的验证。
历史数据库记录状态数据的历史,由levelDB实现。P92
每个历史信息由四元组表示(namespace,writeKey,blockNo,tranNo),最细粒度为交易。
(不同chainCode的数据是逻辑隔离的,通过namespace)
检测点,用于数据恢复,保持数据一致性。数据更新顺序为提交区块账本数据,更新状态数据库,更新历史数据库。 P93
崩溃故障容错CFT 拜占庭容错BFT
共识算法大体分为两类,基于彩票中奖的算法,和基于投票计数的算法。
Fabric中的交易主要分为三大步骤,交易背书(在交易模拟执行后对结果背书的策略),交易排序,交易验证。这三部分都是可插拔的。
交易背书和交易验证都由内置的系统链码实现,故是可替换的。
在提交交易提案的时候可以指定背书策略和验证策略(策略的链码已经上链)。
关于排序节点是否会验证交易内容,答案是不会。
排序服务也可插拔,异步事件方式,提供两个基本接口,
Broadast(blob) 和deliver(seqno,prevhash,blob)。
目前正式版本只支持Apache Kafka的排序服务。
数据隔离通过多通道实现。每个通道有各自的账本。
由于排序服务能收到所有链的交易信息,所以数据隔离不是针对排序服务节点的。如果希望交易数据对排序服务保密,可以对交易信息进行加密。
排序服务创建新通道的过程见P103
应用程序发出的创建新通道的请求成功后,会返回新通道的创世区块。应用程序可以根据这个创世区块确定新链标识、排序服务节点地址等。
Configtxgen 创世块生成工具。
Configtxlator 实现区块和json格式的相互转化。
最后记录两个讲节点,通道和组织关系的博客
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战