// 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
}
Exemple #2
0
// 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
}
Exemple #3
0
// 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)
		}
	}
}