1/27兄弟连区块链技术培训Fabric1.0源代码分析(15)gossip(流言算法)#Fabric1.0源代码笔记之gossip(流言算法)##1、gossip概述gossip,翻译为流言蜚语,即为一种可最终达到一致的算法。最终一致的另外的含义就是,不保证同时达到一致。gossip中有三种基本的操作:*push-A节点将数据(key,value,version)及对应的版本号推送给B节点,B节点更新A中比自己新的数据*pull-A仅将数据key,version推送给B,B将本地比A新的数据(Key,value,version)推送给A,A更新本地*push/pull-与pull类似,只是多了一步,A再将本地比B新的数据推送给B,B更新本地gossip在Fabric中作用:*管理组织内节点和通道信息,并加测节点是否在线或离线。*广播数据,使组织内相同channel的节点同步相同数据。*管理新加入的节点,并同步数据到新节点。gossip代码,分布在gossip、peer/gossip目录下,目录结构如下:*gossip目录:*service目录,GossipService接口定义及实现。*integration目录,NewGossipComponent工具函数。*gossip目录,Gossip接口定义及实现。*comm目录,GossipServer接口实现。*state目录,GossipStateProvider接口定义及实现(状态复制)。*api目录:消息加密服务接口定义。*crypto.go,MessageCryptoService接口定义。*channel.go,SecurityAdvisor接口定义。*peer/gossip目录:*mcs.go,MessageCryptoService接口实现,即mspMessageCryptoService结构体及方法。*sa.go,SecurityAdvisor接口实现,即mspSecurityAdvisor结构体及方法。GossipServer更详细内容,参考:[Fabric1.0源代码笔记之gossip(流言算法)#GossipServer(Gossip服务端)](GossipServer.md)2/27##2、GossipService接口定义及实现###2.1、GossipService接口定义```gotypeGossipServiceinterface{gossip.GossipNewConfigEventer()ConfigProcessorInitializeChannel(chainIDstring,committercommitter.Committer,endpoints[]string)GetBlock(chainIDstring,indexuint64)*common.BlockAddPayload(chainIDstring,payload*proto.Payload)error}//代码在gossip/service/gossip_service.go```补充gossip.Gossip:```gotypeGossipinterface{Send(msg*proto.GossipMessage,peers...*comm.RemotePeer)Peers()[]discovery.NetworkMemberPeersOfChannel(common.ChainID)[]discovery.NetworkMemberUpdateMetadata(metadata[]byte)UpdateChannelMetadata(metadata[]byte,chainIDcommon.ChainID)Gossip(msg*proto.GossipMessage)Accept(acceptorcommon.MessageAcceptor,passThroughbool)(-chan*proto.GossipMessage,-chanproto.ReceivedMessage)JoinChan(joinMsgapi.JoinChannelMessage,chainIDcommon.ChainID)SuspectPeers(sapi.PeerSuspector)Stop()}//代码在gossip/gossip/gossip.go```###2.2、GossipService接口实现GossipService接口实现,即gossipServiceImpl结构体及方法。```gotypegossipSvcgossip.Gossip3/27typegossipServiceImplstruct{gossipSvcchainsmap[string]state.GossipStateProvider//链leaderElectionmap[string]election.LeaderElectionService//选举服务deliveryServicedeliverclient.DeliverServicedeliveryFactoryDeliveryServiceFactorylocksync.RWMutexidMapperidentity.Mappermcsapi.MessageCryptoServicepeerIdentity[]bytesecAdvapi.SecurityAdvisor}//初始化GossipService,调取InitGossipServiceCustomDeliveryFactory()funcInitGossipService(peerIdentity[]byte,endpointstring,s*grpc.Server,mcsapi.MessageCryptoService,secAdvapi.SecurityAdvisor,secureDialOptsapi.PeerSecureDialOpts,bootPeers...string)error//初始化GossipServicefuncInitGossipServiceCustomDeliveryFactory(peerIdentity[]byte,endpointstring,s*grpc.Server,factoryDeliveryServiceFactory,mcsapi.MessageCryptoService,secAdvapi.SecurityAdvisor,secureDialOptsapi.PeerSecureDialOpts,bootPeers...string)error//获取gossipServiceInstancefuncGetGossipService()GossipService//调取newConfigEventer(g)func(g*gossipServiceImpl)NewConfigEventer()ConfigProcessor//初始化通道func(g*gossipServiceImpl)InitializeChannel(chainIDstring,committercommitter.Committer,endpoints[]string)func(g*gossipServiceImpl)configUpdated(configConfig)func(g*gossipServiceImpl)GetBlock(chainIDstring,indexuint64)*common.Blockfunc(g*gossipServiceImpl)AddPayload(chainIDstring,payload*proto.Payload)error//停止gossip服务func(g*gossipServiceImpl)Stop()func(g*gossipServiceImpl)newLeaderElectionComponent(chainIDstring,callbackfunc(bool))election.LeaderElectionServicefunc(g*gossipServiceImpl)amIinChannel(myOrgstring,configConfig)boolfunc(g*gossipServiceImpl)onStatusChangeFactory(chainIDstring,committerblocksprovider.LedgerInfo)func(bool)funcorgListFromConfig(configConfig)[]string4/27//代码在gossip/service/gossip_service.go```####2.2.1、funcInitGossipService(peerIdentity[]byte,endpointstring,s*grpc.Server,mcsapi.MessageCryptoService,secAdvapi.SecurityAdvisor,secureDialOptsapi.PeerSecureDialOpts,bootPeers...string)error```gofuncInitGossipService(peerIdentity[]byte,endpointstring,s*grpc.Server,mcsapi.MessageCryptoService,secAdvapi.SecurityAdvisor,secureDialOptsapi.PeerSecureDialOpts,bootPeers...string)error{util.GetLogger(util.LoggingElectionModule,)returnInitGossipServiceCustomDeliveryFactory(peerIdentity,endpoint,s,&deliveryFactoryImpl{},mcs,secAdv,secureDialOpts,bootPeers...)}funcInitGossipServiceCustomDeliveryFactory(peerIdentity[]byte,endpointstring,s*grpc.Server,factoryDeliveryServiceFactory,mcsapi.MessageCryptoService,secAdvapi.SecurityAdvisor,secureDialOptsapi.PeerSecureDialOpts,bootPeers...string)error{varerrerrorvargossipgossip.Gossiponce.Do(func(){//peer.gossip.endpoint,本节点在组织内的gossipid,或者使用peerEndpoint.AddressifoverrideEndpoint:=viper.GetString(peer.gossip.endpoint);overrideEndpoint!={endpoint=overrideEndpoint}idMapper:=identity.NewIdentityMapper(mcs,peerIdentity)gossip,err=integration.NewGossipComponent(peerIdentity,endpoint,s,secAdv,mcs,idMapper,secureDialOpts,bootPeers...)gossipServiceInstance=&gossipServiceImpl{mcs:mcs,gossipSvc:gossip,chains:make(map[string]state.GossipStateProvider),leaderElection:make(map[string]election.LeaderElectionService),d