def process_vchd_msg(self, msg: ViewChangeDone, sender: str) -> bool:
        """
        Processes ViewChangeDone messages. Once n-f messages have been
        received, decides on a primary for specific replica.

        :param msg: ViewChangeDone message
        :param sender: the name of the node from which this message was sent
        """
        logger.info("{}'s primary selector started processing of ViewChangeDone msg from {} : {}".
                    format(self.name, sender, msg))
        view_no = msg.viewNo
        if self.view_no != view_no:
            self.provider.discard(msg, '{} got Primary from {} for view no {} '
                                       'whereas current view no is {}'.
                                  format(self, sender, view_no, self.view_no),
                                  logMethod=logger.info)
            return False

        new_primary_name = msg.name
        if new_primary_name == self.previous_master_primary:
            self.provider.discard(msg, '{} got Primary from {} for {} who was primary of '
                                       'master in previous view too'.
                                  format(self, sender, new_primary_name),
                                  logMethod=logger.info)
            return False

        # Since a node can send ViewChangeDone more than one time
        self._on_verified_view_change_done_msg(msg, sender)
        # TODO why do we check that after the message tracking
        if self.provider.has_primary():
            self.provider.discard(msg, "it already decided primary which is {}".
                                  format(self.provider.current_primary_name()), logger.info)
            return False

        self._start_selection()
def process_vchd_msg ( self , msg : ViewChangeDone , sender : str ) -> bool : logger . info ( "{}'s primary selector started processing of ViewChangeDone msg from {} : {}" . format ( self . name , sender , msg ) ) view_no = msg . viewNo if self . view_no != view_no : self . provider . discard ( msg , '{} got Primary from {} for view no {} ' 'whereas current view no is {}' . format ( self , sender , view_no , self . view_no ) , logMethod = logger . info ) return False new_primary_name = msg . name if new_primary_name == self . previous_master_primary : self . provider . discard ( msg , '{} got Primary from {} for {} who was primary of ' 'master in previous view too' . format ( self , sender , new_primary_name ) , logMethod = logger . info ) return False self . _on_verified_view_change_done_msg ( msg , sender ) if self . provider . has_primary ( ) : self . provider . discard ( msg , "it already decided primary which is {}" . format ( self . provider . current_primary_name ( ) ) , logger . info ) return False self . _start_selection ( )
Processes ViewChangeDone messages. Once n-f messages have been
        received, decides on a primary for specific replica.

        :param msg: ViewChangeDone message
        :param sender: the name of the node from which this message was sent