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)
}
浙公网安备 33010602011771号