admin管理员组文章数量:1642450
一.共识机制
达成共识需要3个阶段,交易背书,交易排序,交易验证
- 交易背书:模拟的
- 交易排序:确定交易顺序,最终将排序好的交易打包区块分发
- 交易验证:区块存储前要进行一下交易验证
二.orderer节点的作用
- 交易排序
- 目的:保证系统的最终一致性(有限状态机)
- solo:单节点排序
- kafka:外置的分布式消息队列
- 区块分发
- orderer中的区块并不是最终持久化的区块
- 是一个中间状态的区块
- 包含了所有交易,不管是有效还是无效,都会打包传给组织的锚节点
- 多通道的数据隔离
- 客户端可以使用某个通道,发送交易
三.源码目录
- 从goland中阅读
- 源码目录
- bccsp:与密码学相关的,加密,数字签名,证书,将密码学中的函数抽象成了接口,方便调用和扩展
- bddtests:行为驱动开发,从需求直接到开发
- common:公共库、错误处理、日志出项,账本存储,相关工具
- core:是fabric的核心库,子目录是各个模块的目录 / comm:网络通信相关
- devenv:官方提供的开发环境,使用的是Vagrant
- docs:文档
- events:事件监听机制
- examples:例子程序
- gossip:通信协议,组织内部的通信,区块同步
- gotools:用于编译
- images:docker镜像相关
- msp:成员服务管理,member serivce provider,读取证书做签名
- orderer:排序节点
- peer:peer节点
- proposals:用于扩展,新功能的提案
- protos:数据结构的定义
四.共识机制源码
orderer节点的源码
- 首先看orderer目录下的main.go ,main.go里有一个NewServer可以进入server.go
main.go中func main() 主要起到判断作用,如果接收到的是start命令,就加载和初始化各种配置,如果接收到的是version指令,就打印版本号;之后在下面定义了上面的各种方法。
func main() {
kingpin.Version("0.0.1")
//判断接受到的参数Args
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
// 如果接受到"start" command
case start.FullCommand():
logger.Infof("Starting %s", metadata.GetVersionInfo())
//加载配置
conf := config.Load()
//初始化日志级别
//生产环境下日志级别调高
initializeLoggingLevel(conf)
//初始化profile,go内置的观察程序运行的工具
//可以通过http调用
initializeProfilingService(conf)
//初始化grpc服务端
grpcServer := initializeGrpcServer(conf)
//加载msp签名证书
initializeLocalMsp(conf)
//msp证书给签名者实例化
signer := localmsp.NewSigner()
//初始化链的管理者(也就是主节点)
manager := initializeMultiChainManager(conf, signer)
//实例化服务
server := NewServer(manager, signer)
//绑定服务
ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
logger.Info("Beginning to serve requests")
//启动服务
grpcServer.Start()
// 如果接受到"version" command
case version.FullCommand():
//打印版本号
fmt.Println(metadata.GetVersionInfo())
}
}
我们来看下初始化管理者的代码
func initializeMultiChainManager(conf *config.TopLevel, signer crypto.LocalSigner) multichain.Manager {
//创建账本工厂,产生临时区块
lf, _ := createLedgerFactory(conf)
//判断链是否存在
if len(lf.ChainIDs()) == 0 {
//链不存在
//启动引导链
initializeBootstrapChannel(conf, lf)
} else {
logger.Info("Not bootstrapping because of existing chains")
}
//实例化共识机制
//有solo和kafka两种模式
consenters := make(map[string]multichain.Consenter)
consenters["solo"] = solo.New()
consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version)
return multichain.NewManagerImpl(lf, consenters, signer)
}
- orderer的配置文件在orderer.yaml中,监听的地址是127.0.0.1;监听的端口是7050;BCCSP是密码学,账本存储最终还是存储到硬盘中。
- 接下来咱们看下实例化服务server.go,这里面定义了交易收集和广播区块。
type server struct {
//交易收集
bh broadcast.Handler
//广播区块
dh deliver.Handler
}
我们具体看下交易收集:broadcast.go
func (bh *handlerImpl) Handle(srv ab.AtomicBroadcast_BroadcastServer) error {
logger.Debugf("Starting new broadcast loop")
for {
//接收交易
msg, err := srv.Recv()
if err == io.EOF {
logger.Debugf("Received EOF, hangup")
return nil
}
if err != nil {
logger.Warningf("Error reading from stream: %s", err)
return err
}
payload, err := utils.UnmarshalPayload(msg.Payload)
if err != nil {
logger.Warningf("Received malformed message, dropping connection: %s", err)
return srv.Send(&ab.BroadcastResponse{Status: cb.Status_BAD_REQUEST})
}
//验证消息体的内容,有错误则返回Status_
版权声明:本文标题:超级账本hyperledger fabric第五集:共识排序及源码阅读 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729331929a1196498.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论