美文网首页
Hyperledger-Fabric源码分析(更新通道)

Hyperledger-Fabric源码分析(更新通道)

作者: Pillar_Zhong | 来源:发表于2019-04-09 00:33 被阅读0次

如果看完创建与加入通道的部分,这里基本上比他们要更简单。

前面重复的部分我们就不再赘述,直接来到orderer来处理配置更新的部分。

func (bh *Handler) ProcessMessage(msg *cb.Envelope, addr string) (resp *ab.BroadcastResponse) {
   ...

   if !isConfig {
   ...
   } else { // isConfig

      config, configSeq, err := processor.ProcessConfigUpdateMsg(msg)

      err = processor.Configure(config, configSeq)
      
   }

   return &ab.BroadcastResponse{Status: cb.Status_SUCCESS}
}

创建通道的部分,我们已经知道当没有通道的时候,processor是SystemChannel来处理,而这里是完全不同的情况,会用StandardChannel来托管

StandardChannel

ProcessConfigUpdateMsg

func (s *StandardChannel) ProcessConfigUpdateMsg(env *cb.Envelope) (config *cb.Envelope, configSeq uint64, err error) {
   logger.Debugf("Processing config update message for channel %s", s.support.ChainID())

   // Call Sequence first.  If seq advances between proposal and acceptance, this is okay, and will cause reprocessing
   // however, if Sequence is called last, then a success could be falsely attributed to a newer configSeq
   seq := s.support.Sequence()
   err = s.filters.Apply(env)
   if err != nil {
      return nil, 0, err
   }

   configEnvelope, err := s.support.ProposeConfigUpdate(env)
   if err != nil {
      return nil, 0, err
   }

   config, err = utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, s.support.ChainID(), s.support.Signer(), configEnvelope, msgVersion, epoch)
   if err != nil {
      return nil, 0, err
   }
   
   err = s.filters.Apply(config)
   if err != nil {
      return nil, 0, err
   }

   return config, seq, nil
}

这里首先会筛选一遍,创建通道的时候我们知道SystemChannel的过滤器,这里我们来看下StandardChannel的过滤器。

  • func CreateStandardChannelFilters(filterSupport channelconfig.Resources) *RuleSet {
       ordererConfig, ok := filterSupport.OrdererConfig()
       if !ok {
          logger.Panicf("Missing orderer config")
       }
       return NewRuleSet([]Rule{
          EmptyRejectRule,
          NewExpirationRejectRule(filterSupport),
          NewSizeFilter(ordererConfig),
          NewSigFilter(policies.ChannelWriters, filterSupport),
       })
    }
    
    • envelope的签名身份不能过期
    • 消息大小不能超标
    • 要满足/channel/writer的权限,也就是Any member,看你配置。
  • 如果过滤器都没问题,接下来处理配置。里面主要是将变更的配置与现有通道配置进行合并,产出一份完整的通道配置。

  • 之后组装HeaderType_CONFIG类型的SignedProposal

  • 再次做一遍筛选

  • 之后的流程就是发给orderer的共识服务里去流转,中间的流程跟通道创建类似,这里直接跳到最终接收HeaderType_CONFIG的地方。

WriteConfigBlock

func (bw *BlockWriter) WriteConfigBlock(block *cb.Block, encodedMetadataValue []byte) {
   ...

   switch chdr.Type {
   case int32(cb.HeaderType_ORDERER_TRANSACTION):
      ...
   case int32(cb.HeaderType_CONFIG):
      configEnvelope, err := configtx.UnmarshalConfigEnvelope(payload.Data)

      err = bw.support.Validate(configEnvelope)

      bundle, err := bw.support.CreateBundle(chdr.ChannelId, configEnvelope.Config)
     
      bw.support.Update(bundle)
   default:
      logger.Panicf("Told to write a config block with unknown header type: %v", chdr.Type)
   }

   bw.WriteBlock(block, encodedMetadataValue)
}
  • 这里又将configEnvelope转换成bundle。这个过程已经转两次了,实在是浪费。不管了,配置部分就是这样,我习惯了。
  • 为了更新配置,当然了需要去更新通道绑定的bundle,这次毫无意外调用了bw.support.Update(bundle),这里就是最终的目的,通道配置更新。

小结

之后就是写入本地账本,然后同步给orderer,然后被leaderpeer拉取,然后再同步非peer成员,然后整个世界都同步配置了。而全部都是通过update bundle来实现配置更新。

相关文章

网友评论

      本文标题:Hyperledger-Fabric源码分析(更新通道)

      本文链接:https://www.haomeiwen.com/subject/ijfviqtx.html