Example #1
0
def testPrimaryElectionCase5(case5Setup, looper, keySharedNodes):
    """
    Case 5 - A node making primary declarations for a multiple other nodes.
    Consider 4 nodes A, B, C, and D. Lets say node B is malicious and
    declares node C as primary to all nodes.
    Again node B declares node D as primary to all nodes.
    """
    nodeSet = keySharedNodes
    A, B, C, D = nodeSet.nodes.values()

    looper.run(checkNodesConnected(nodeSet))

    BRep = Replica.generateName(B.name, 0)
    CRep = Replica.generateName(C.name, 0)
    DRep = Replica.generateName(D.name, 0)

    # Node B first sends PRIMARY msgs for Node C to all nodes
    B.send(Primary(CRep, 0, B.viewNo))
    # Node B sends PRIMARY msgs for Node D to all nodes
    B.send(Primary(DRep, 0, B.viewNo))

    # Ensure elections are done
    ensureElectionsDone(looper=looper, nodes=nodeSet, retryWait=1, timeout=45)

    # All nodes from node A, node C, node D(node B is malicious anyway so not
    # considering it) should have primary declarations for node C from node B
    #  since node B first nominated node C
    for node in [A, C, D]:
        logger.debug(
            "node {} should have primary declaration for C from node B"
            .format(node))
        assert node.elector.primaryDeclarations[0][BRep] == CRep
Example #2
0
def testPrimaryElectionCase4(case4Setup, looper):
    """
    Case 4 - A node making multiple primary declarations for a particular node.
    Consider 4 nodes A, B, C and D. Lets say node B is malicious and is
    repeatedly declaring Node D as primary
    """
    allNodes = case4Setup
    A, B, C, D = allNodes

    looper.run(checkNodesConnected(allNodes))

    # Node B sends multiple declarations of node D's 0th protocol instance as
    # primary to all nodes
    for i in range(5):
        B.send(Primary(D.name, 0, B.viewNo))

    # No node from node A, node C, node D(node B is malicious anyway so not
    # considering it) should have more than one primary declaration for node
    # D since node D is slow. The one primary declaration for node D,
    # that nodes A, C and D might have would be because of node B
    def x():
        primDecs = list(node.elector.primaryDeclarations[0].values())
        assert primDecs.count(D.name) <= 1

    for node in (A, C, D):
        looper.run(eventually(x, retryWait=.5, timeout=2))

    ensureElectionsDone(looper=looper, nodes=allNodes,
                        retryWait=1, timeout=45)

    # Node D should not have any primary replica
    assert not D.hasPrimary
Example #3
0
    def sendPrimary(self, instId: int, primaryName: str):
        """
        Declare a primary and broadcast the message.

        :param instId: the instanceId to which the primary belongs
        :param primaryName: the name of the primary replica
        """
        replica = self.replicas[instId]
        self.primaryDeclarations[instId][replica.name] = primaryName
        self.scheduledPrimaryDecisions[instId] = None
        logger.debug("{} declaring primary as: {} on the basis of {}".format(
            replica, primaryName, self.nominations[instId]))
        self.send(Primary(primaryName, instId, self.viewNo))
Example #4
0
 def getElectionMsgsForInstance(self, instId: int) -> \
         Sequence[Union[Nomination, Primary]]:
     """
     Get nomination and primary messages for instance with id `instId`.
     """
     msgs = []
     replica = self.replicas[instId]
     # If a primary for this instance has been selected then send a
     # primary declaration for the selected primary
     if replica.isPrimary is not None:
         msgs.append(Primary(replica.primaryName, instId, self.viewNo))
     else:
         # If a primary for this instance has not been selected then send
         # nomination and primary declaration that this node made for the
         # instance with id `instId`
         if self.didReplicaNominate(instId):
             msgs.append(Nomination(self.nominations[instId][
                                        replica.name],
                                    instId, self.viewNo))
         if self.didReplicaDeclarePrimary(instId):
             msgs.append(Primary(self.primaryDeclarations[instId][replica.name],
                                 instId,
                                 self.viewNo))
     return msgs
Example #5
0
def testBlacklistNodeOnMultiplePrimaryDeclarations(looper, keySharedNodes,
                                                   ready):
    """
    A node that sends multiple primary declarations must be blacklisted by
    other nodes
    """
    nodeSet = keySharedNodes
    A, B, C, D = nodeSet.nodes.values()

    # B sends more than 2 primary declarations
    for i in range(3):
        B.send(Primary(D.name, 0, B.viewNo))

    # B should be blacklisted by A, C, D
    def chk():
        for node in A, C, D:
            assert node.isNodeBlacklisted(B.name)

    looper.run(eventually(chk, retryWait=1, timeout=3))