peer join 流程

1、sdk或peer发起join channel请求,收到消息的peer执行系统级智能合约(cscc)invoke方法。

2、根据发起请求自带的block参数,创建相应的chain信息,包括chain对应的ledger,并将该block数据提交到该ledger中。

3、peer将创建好的chain信息同步到相同组织其它的peer中。

4、peer将创建好的chain信息与orderer通信,并建立与orderer之间在该channerl上的数据传输通道。

5、创建chain创建成果通知消息,发送给监听此事件的peer。

peer端处理流程

发送创建channel的api到Ordering服务,会在目录下生成myc2.block
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2

这将返回一个创造块 - myc2.block - 你可以发出连接命令。 接下来,发送一个joinChannel API到peer0,把block作为参数传入。 channel定义:

CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block

Joinchain为系统合约cscc Join操作的主函数,主要涉及peer中chain的创建、chain的初始化两个主要步骤。

func joinChain(blockBytes []byte) pb.Response {
       block, err := utils.GetBlockFromBlockBytes(blockBytes)
       //peer根据block创建chain
       err = peer.CreateChainFromBlock(block);

       chainID, err := utils.GetChainIDFromBlock(block)

       //初始化chain
       peer.InitChain(chainID)
       //发送join成功事件,通知相关订阅者
       err := producer.SendProducerBlockEvent(block)
}

CreateChainFromBlock函数实现了peer根据block创建chain流程

func CreateChainFromBlock(cb *common.Block) error {
       //从Block中获取chainid
       cid, err := utils.GetChainIDFromBlock(cb)

       //创建相应chainid的ledger,并将block提交到刚创建好的ledger中
       var l ledger.PeerLedger
       if l, err = ledgermgmt.CreateWithGenesisBlock(cb); err != nil {
              return fmt.Errorf("Cannot create ledger from genesis block, due to %s", err)
       }
       //根据chainid、ledger、block创建新的chain
       return createChain(cid, l, cb)
}
func (provider *Provider) CreateWithGenesisBlock(genesisBlock *common.Block) (ledger.PeerLedger, error) {
        //创建相应chainid的ledger
	    ledger, err := provider.openInternal(ledgerID)
	    //将block提交到刚创建好的ledger中
		if err := ledger.Commit(genesisBlock); err != nil {
		ledger.Close()
		return nil, err
	}

createChain的处理流程

func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {
  	 //获取cb block中的第0块block的envelope结构:一个包含数据和签名的数据结构
     envelopeConfig, err := utils.ExtractEnvelope(cb, 0)
  
     //创建peer中关于该chainid的config基础信息
  	 configtxInitializer := configtx.NewInitializer()
	 gossipEventer := service.GetGossipService().NewConfigEventer()

     //初始化相应chainid的channel
  	 c := committer.NewLedgerCommitter(ledger, txvalidator.NewTxValidator(cs))
	 ordererAddresses := configtxManager.ChannelConfig().OrdererAddresses()
     service.GetGossipService().InitializeChannel(cs.ChainID(), c, ordererAddresses)
  
    //新增的chain
  	chains.list[cid] = &chain{
		cs:        cs,
		cb:        cb,
		committer: c,
	}

初始化相应channel

func (g *gossipServiceImpl) InitializeChannel(chainID string, committer committer.Committer, endpoints []string) {
    //创建gossip,gossip用于同一个组织中peer的消息状态同步
    g.chains[chainID] = state.NewGossipStateProvider(chainID, g, committer, g.mcs)
  	if g.deliveryService == nil {
		var err error
        //与orderer的连接不存在,需要创建grpc通信
		g.deliveryService, err = g.deliveryFactory.Service(gossipServiceInstance, endpoints, g.mcs)
    }
  
  		if leaderElection {
            //直接指定该peer在该组织中为leader节点,负责Block消息的同步
			logger.Debug("Delivery uses dynamic leader election mechanism, channel", chainID)
			g.leaderElection[chainID] = g.newLeaderElectionComponent(chainID, g.onStatusChangeFactory(chainID, committer))
		} else if isStaticOrgLeader {
			logger.Debug("This peer is configured to connect to ordering service for blocks delivery, channel", chainID)
            //启动peer获取Orderer中block并将block同步到其他peer,如果存在其它peer与该peer组成为一个组织
			g.deliveryService.StartDeliverForChannel(chainID, committer)
		} 
posted on 2017-04-15 14:12  云中大卫  阅读(1129)  评论(0)    收藏  举报