Orderer启动后,内部保存了创世块的默认配置,生成Channel文件后,通过Peer节点可以将CongfigUpdate提交给Orderer处理,Orderer会创建一个新的Channel,并返回这个Channel的第一个Block。
1.使用
使用peer channel create命令就可以通知Orderer生产一个Channel,-t
指定了peer的超时时间为50s,-c
指定了要创建的Channel名称,需要与-f
中的一致。在这个命令的执行过程中,peer作为一个Orderer的client发出请求,不需要提供服务。设置环境变量的目的是因为Peer要初始化MSP,对UpdateConfig签名后发送给Orderer。
export set CORE_PEER_LOCALMSPID=CoreMSP
export set CORE_PEER_MSPCONFIGPATH=/../../crypto-config/peerOrganizations/core.jianshu.com/users/Admin@core.jianshu.com/msp
peer channel create -t 50 -o orderer.jianshu.com:7050 -c mychannel -f mychannel.tx
2.主要流程
2.1 Peer端主要流程
- 初始化ChannelCmdFactory,这个类用来提供peer作为client需要的客户端,包括三个:EndorserClient,BroadcastClient和DeliverClient,由于创建Channel时不需要背书,因此只使用了后面两个Client。BroadcastClient用来给Orderer发送ConfigUpdate,DeliverClient发送SeekInfo拉去Channel的首个Block。
- 获取channel文件中的Envelope,可以参考Fabric源码分析-生成Channel文件,之后反序列化,检查合理性并对ConfigUpdate进行签名,再封装为一个Envelope。
- 将签名后的Envelope通过BroadcastClient发送给Orderer
- 使用DeliverClient拉取Channel的第一个Block,写入文件中,SeekInfo中的Behavior设置为了SeekInfo_BLOCK_UNTIL_READY,会阻塞等待返回。
2.1 Orderer端主要流程
创建Channel的主要逻辑在Orderer端,Orderer端Boardcast服务流程可以参考Fabric源码分析-Orderer启动2.5节。主要流程是:
- 在Orderer启动时,根据Fabric源码分析-Orderer启动中的描述,会根据创世块创建一个默认的
testchannelid
的账本,作为系统Channel;ConfigUpdate中指定了Channel/Consortium
和Channel/Application/Organizations
,将修改与创世块中的配置整合起来,形成一个新的ConfigGroup - 对最新的ConfigGroup创建Bundle,Bundle是ConfigGroup的视图,内部保存了操作资源的对象,如configtxManager/MSPManager/policyManager。使用configtxManager对内部的ConfigUpdate进行验证,返回一个ConfigEnvelope,ConfigEnvelope中的LastUpdate为我们传入的ConfigUpdate的Env,之后对其签名,封装为
HeaderType_ORDERER_TRANSACTION
类型的交易Envelope - 调用consener的Configure,以
solo
为例,会交给ChainSupport的Chain处理(orderer/consensus/solo/consensus.go中),其会发送给SendChan,如果是config类型,会使用cut()获取当前block,因为此时还没有,因此会创建第一个Block并写入文件中。
3.程序实现
3.1 相关类
- Orderer的Boardcast服务收到请求后,由
orderer/common/broadcast/broadcast.go
中的handlerImpl处理 - processor由NewHandlerImpl传入的Registrar的BroadcastChannelSupport返回,Registrar在
orderer/common/multichannel/registrar.go
中定义,返回的process是systemChannel,systemChannel是在Orderer启动时创建的newChainSupport返回的ChainSupport,ChainSupport中的Processor为msgprocessor.NewStandardChannel
创建的StandardChannel
- templator 在NewSystemChannel的时候指定,使用
msgprocessor.NewDefaultTemplator
返回了DefaultTemplator,在systemchannel.go
中定义
3.2 ConfigEnvelope
ConfigEnvelope被设计为一个包含了所有配置的对象,根据下面的规则生成:
- 查找已经存在的配置
- 记录被修改的配置ConfigValue, ConfigPolicy, ConfigGroup
- 将config中的ConfigGroups到ConfigUpdate的ReadSet
- 添加额外的依赖项到ConfigUpdate的ReadSet
- 修改config属性,每次将版本号加1,将修改内容设置到ConfigUpdate的WriteSet,未被修改的元素会被放在已经存在的ReadSet
- 将ConfigUpdate保存到ConfigUpdateEnvelope的update中,添加需要的签名
- 提交新的Config到Orderer,其中的Payload是序列化后的ConfigEnvelope