// NewGossipService creates a gossip instance attached to a gRPC server func NewGossipService(conf *Config, s *grpc.Server, mcs api.MessageCryptoService, selfIdentity api.PeerIdentityType, dialOpts ...grpc.DialOption) Gossip { var c comm.Comm var err error idMapper := identity.NewIdentityMapper(mcs) lgr := util.GetLogger(util.LOGGING_GOSSIP_MODULE, conf.ID) if s == nil { c, err = createCommWithServer(conf.BindPort, idMapper, selfIdentity) } else { c, err = createCommWithoutServer(s, idMapper, selfIdentity, dialOpts...) } if err != nil { lgr.Error("Failed instntiating communication layer:", err) return nil } g := &gossipServiceImpl{ selfIdentity: selfIdentity, presumedDead: make(chan common.PKIidType, presumedDeadChanSize), idMapper: idMapper, disc: nil, mcs: mcs, comm: c, conf: conf, ChannelDeMultiplexer: comm.NewChannelDemultiplexer(), logger: lgr, toDieChan: make(chan struct{}, 1), stopFlag: int32(0), stopSignal: &sync.WaitGroup{}, goRoutines: make([]uint64, 0), includeIdentityPeriod: time.Now().Add(conf.PublishCertPeriod), } g.emitter = newBatchingEmitter(conf.PropagateIterations, conf.MaxPropagationBurstSize, conf.MaxPropagationBurstLatency, g.sendGossipBatch) g.discAdapter = g.newDiscoveryAdapter(selfIdentity) g.disSecAdap = newDiscoverySecurityAdapter(idMapper, mcs, c, g.logger) g.disc = discovery.NewDiscoveryService(conf.BootstrapPeers, discovery.NetworkMember{ Endpoint: conf.SelfEndpoint, PKIid: g.comm.GetPKIid(), Metadata: []byte{}, }, g.discAdapter, g.disSecAdap) g.msgStore = newMessageStore(proto.NewGossipMessageComparator(g.conf.MaxMessageCountToStore), func(m interface{}) { g.blocksPuller.Remove(m.(*proto.GossipMessage)) }) g.blocksPuller = g.createBlockPuller() g.certStore = newCertStore(g.createCertStorePuller(), idMapper, selfIdentity, mcs) g.logger.SetLevel(logging.WARNING) go g.start() return g }
func newCertStore(puller pull.Mediator, idMapper identity.Mapper, selfIdentity api.PeerIdentityType, mcs api.MessageCryptoService) *certStore { selfPKIID := idMapper.GetPKIidOfCert(selfIdentity) logger := util.GetLogger("certStore", string(selfPKIID)) if err := idMapper.Put(selfPKIID, selfIdentity); err != nil { logger.Error("Failed associating self PKIID to cert:", err) panic(fmt.Errorf("Failed associating self PKIID to cert: %v", err)) } certStore := &certStore{ mcs: mcs, pull: puller, idMapper: idMapper, selfIdentity: selfIdentity, logger: logger, } certStore.logger = util.GetLogger("certStore", string(selfPKIID)) if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil { certStore.logger.Panic("Failed associating self PKIID to cert:", err) } puller.Add(certStore.createIdentityMessage()) puller.RegisterMsgHook(pull.ResponseMsgType, func(_ []string, msgs []*proto.GossipMessage, _ comm.ReceivedMessage) { for _, msg := range msgs { pkiID := common.PKIidType(msg.GetPeerIdentity().PkiID) cert := api.PeerIdentityType(msg.GetPeerIdentity().Cert) if err := certStore.idMapper.Put(pkiID, cert); err != nil { certStore.logger.Warning("Failed adding identity", cert, ", reason:", err) } } }) puller.Add(certStore.createIdentityMessage()) return certStore }
func NewPullMediator(config PullConfig, sndr Sender, memSvc MembershipService, idExtractor proto.IdentifierExtractor, msgCons proto.MsgConsumer) Mediator { p := &pullMediatorImpl{ msgCons: msgCons, msgType2Hook: make(map[PullMsgType][]MessageHook), idExtractor: idExtractor, config: config, logger: util.GetLogger("Pull", config.Id), itemId2msg: make(map[string]*proto.GossipMessage), memBvc: memSvc, Sender: sndr, } p.engine = algo.NewPullEngine(p, config.PullInterval) return p }
// NewCommInstanceWithServer creates a comm instance that creates an underlying gRPC server func NewCommInstanceWithServer(port int, idMapper identity.Mapper, peerIdentity api.PeerIdentityType, dialOpts ...grpc.DialOption) (Comm, error) { var ll net.Listener var s *grpc.Server var secOpt grpc.DialOption if len(dialOpts) == 0 { dialOpts = []grpc.DialOption{grpc.WithTimeout(dialTimeout)} } if port > 0 { s, ll, secOpt = createGRPCLayer(port) dialOpts = append(dialOpts, secOpt) } commInst := &commImpl{ PKIID: idMapper.GetPKIidOfCert(peerIdentity), idMapper: idMapper, logger: util.GetLogger(util.LOGGING_COMM_MODULE, fmt.Sprintf("%d", port)), peerIdentity: peerIdentity, opts: dialOpts, port: port, lsnr: ll, gSrv: s, msgPublisher: NewChannelDemultiplexer(), lock: &sync.RWMutex{}, deadEndpoints: make(chan common.PKIidType, 100), stopping: int32(0), exitChan: make(chan struct{}, 1), subscriptions: make([]chan ReceivedMessage, 0), blackListedPKIIDs: make([]common.PKIidType, 0), } commInst.connStore = newConnStore(commInst, commInst.logger) commInst.idMapper.Put(idMapper.GetPKIidOfCert(peerIdentity), peerIdentity) if port > 0 { go func() { commInst.stopWG.Add(1) defer commInst.stopWG.Done() s.Serve(ll) }() proto.RegisterGossipServer(s, commInst) } commInst.logger.SetLevel(logging.WARNING) return commInst, nil }
// NewDiscoveryService returns a new discovery service with the comm module passed and the crypto service passed func NewDiscoveryService(bootstrapPeers []string, self NetworkMember, comm CommService, crypt CryptoService) Discovery { d := &gossipDiscoveryImpl{ endpoint: self.Endpoint, incTime: uint64(time.Now().UnixNano()), metadata: self.Metadata, pkiID: self.PKIid, seqNum: uint64(0), deadLastTS: make(map[string]*timestamp), aliveLastTS: make(map[string]*timestamp), id2Member: make(map[string]*NetworkMember), cachedMembership: &proto.MembershipResponse{ Alive: make([]*proto.AliveMessage, 0), Dead: make([]*proto.AliveMessage, 0), }, crpypt: crypt, bootstrapPeers: bootstrapPeers, comm: comm, lock: &sync.RWMutex{}, toDieChan: make(chan struct{}, 1), toDieFlag: int32(0), logger: util.GetLogger(util.LOGGING_DISCOVERY_MODULE, self.Endpoint), } d.logger.SetLevel(logging.WARNING) go d.periodicalSendAlive() go d.periodicalCheckAlive() go d.handleMessages() go d.periodicalReconnectToDead() go d.handlePresumedDeadPeers() d.connect2BootstrapPeers(bootstrapPeers) d.logger.Info("Started", self, "incTime is", d.incTime) return d }