// handleChainPublication processes an Authenticated Broadcast publication. // It takes as input a publication. func (s *Subscriber) handleChainPublication(pub *pb.Publication) bool { // Verify MACs verified := s.verifyChainMACs(pub, s.chainRange) if !verified { // fmt.Printf("Not verified\n") return false } // fmt.Printf("Verified\n") // Make the map so not trying to access nil reference if s.pubsLearned[pub.PublisherID] == nil { s.pubsLearned[pub.PublisherID] = make(map[int64]string) } // If already learned this publication if s.pubsLearned[pub.PublisherID][pub.PublicationID] != "" { // fmt.Printf("Already learned publication %v from publisher %v.\n", pub.PublicationID, pub.PublisherID) return false } s.pubsLearned[pub.PublisherID][pub.PublicationID] = common.GetInfo(pub) //fmt.Printf("Learned publication %v from publisher %v.\n", pub.PublicationID, pub.PublisherID) return true }
// handleBrbPublication processes a Bracha's Reliable Broadcast publication. // It takes as input a publication. func (s *Subscriber) handleBrbPublication(pub *pb.Publication) bool { foundQuorum := false // Make the map so not trying to access nil reference if s.pubsReceived[pub.PublisherID] == nil { s.pubsReceived[pub.PublisherID] = make(map[int64]map[uint64]string) } // Make the map so not trying to access nil reference if s.pubsReceived[pub.PublisherID][pub.PublicationID] == nil { s.pubsReceived[pub.PublisherID][pub.PublicationID] = make(map[uint64]string) } // Publication has not been received yet for this publisher ID, publication ID, broker ID if s.pubsReceived[pub.PublisherID][pub.PublicationID][pub.BrokerID] == "" { // So record it s.pubsReceived[pub.PublisherID][pub.PublicationID][pub.BrokerID] = common.GetInfo(pub) // Check if there is a quorum yet for this publisher ID and publication ID foundQuorum = s.checkQuorum(pub.PublisherID, pub.PublicationID) if foundQuorum && pub.PublicationID < 0 { s.handleHistoryPublication(pub) } } return foundQuorum }
// handleEcho handles echo requests from Bracha's Reliable Broadcast. // It takes the request as input. func (b Broker) handleEcho(pub *pb.Publication) { // fmt.Printf("Handle echo Publication %v, Publisher %v, Broker %v.\n", pub.PublicationID, pub.PublisherID, pub.BrokerID) // Make the map so not trying to access nil reference if b.echoesReceived[pub.PublisherID] == nil { b.echoesReceived[pub.PublisherID] = make(map[int64]map[uint64]string) } // Make the map so not trying to access nil reference if b.echoesReceived[pub.PublisherID][pub.PublicationID] == nil { b.echoesReceived[pub.PublisherID][pub.PublicationID] = make(map[uint64]string) } // Echo has not been received yet for this publisher ID, publication ID, broker ID if b.echoesReceived[pub.PublisherID][pub.PublicationID][pub.BrokerID] == "" { // So record it b.echoesReceived[pub.PublisherID][pub.PublicationID][pub.BrokerID] = common.GetInfo(pub) // Check if there is a quorum yet for this publisher ID and publication ID foundQuorum := b.checkEchoQuorum(pub.PublisherID, pub.PublicationID) if b.readiesSent[pub.PublisherID] == nil { b.readiesSent[pub.PublisherID] = make(map[int64]bool) } // If this publication has not been readied yet if foundQuorum && b.readiesSent[pub.PublisherID][pub.PublicationID] == false { // Update broker ID pub.BrokerID = b.localID // "Send" the ready request to itself b.fromBrokerReadyCh <- *pub // Send the ready to all other brokers b.remoteBrokersMutex.RLock() for _, remoteBroker := range b.remoteBrokers { if remoteBroker.toReadyCh != nil { remoteBroker.toReadyCh <- *pub if len(remoteBroker.toReadyCh) > b.toBrbChLen/2 { b.setBusy() } } } b.remoteBrokersMutex.RUnlock() // Send the publication to all subscribers b.subscribersMutex.RLock() for _, subscriber := range b.subscribers { // Only if they are interested in the topic if subscriber.toCh != nil && subscriber.topics[pub.TopicID] == true { subscriber.toCh <- *pub if len(subscriber.toCh) > b.toSubscriberChLen/2 { b.setBusy() } } } b.subscribersMutex.RUnlock() // Mark this publication as readied b.readiesSent[pub.PublisherID][pub.PublicationID] = true // fmt.Printf("handleEcho: Sent readies for publication %v by publisher %v.\n", pub.PublicationID, pub.PublisherID) // For performance testing, get the time of the last step for this broker b.incrementPublicationCount(pub) } } }