Example #1
0
def handle_message(type, message, sender):
    """ Used to handle an incoming message sent by another node (heh-heh-heyyyy!).

        Args:
            type (str): Type of message to process as; unknown types are ignored.
            message (str): Payload to deliver to subcomponent based on type.
            sender (str): Sender of message (primarily used to find key in PKI).
    """
    print("SENDER", sender)

    if type == "addblock":
        # Add block to blockchain
        block = string_to_block(message)
        from blockchain import chaindb
        chaindb.connection.close()
        chaindb.db.close()
        importlib.reload(chaindb)
        chain = chaindb.chain
        print(block)
        print(block.is_valid())
        if not block.hash in chain.blocks and block.is_valid():
            # if it's a valid block we haven't seen, retransmit
            chain.add_block(block)
            gossip_message(type, message)
        chaindb.connection.close()
        chaindb.db.close()

    if type == "synchrony-start":
        # Kick off the round-based synchrony tracker
        if not synchrony.is_started():
            synchrony.receive_start_message()
            gossip_message(type, "")

    if type == "ba-start":
        # Kick off the BA protocol
        if config.ba == None:
            from byzantine_agreement.simple_ba import SimplePKIBA
            from byzantine_agreement.byzantine_ba import ByzantineSimplePKIBA
            if not config.node_id in config.BYZANTINE_NODES:
                config.ba = SimplePKIBA(int(message))
            else:
                config.ba = ByzantineSimplePKIBA(int(message))
            gossip_message(type, message)

    if type == "ba-vote":
        # Send confirmed vote to our BA protocol
        config.ba.process_vote(message)
Example #2
0
 def test_ba_proposals(self):
     SimplePKIBA.run_protocol_loop = lambda x: x  # disable protocol loop to prevent hanging thread
     curr_ba = SimplePKIBA(1)
     import config
     config.node_id = 4
     self.assertEqual(curr_ba.calculate_votes_for(0), [])
     self.assertEqual(curr_ba.calculate_votes_for(1000), [])
     self.assertEqual(curr_ba.calculate_votes_for(-1), [])
     # check that relevant data stuctures are still empty
     self.assertEqual(curr_ba.s_i, [])
     self.assertEqual(curr_ba.votes, {})
     self.assertEqual(curr_ba.signatures, {})
     # single proposal, some votes
     self.reset_ba(curr_ba)
     # mock in votes and signatures
     curr_ba.votes = {"hi": set([1, 2])}
     curr_ba.signatures = {"hi": [(1, "a"), (2, "b")]}
     self.assertEqual(
         curr_ba.calculate_votes_for(0),
         ['hi'])  # hi should be added to S_i here (reaches vote threshold)
     # ensure data structures are correctly updated
     self.assertEqual(curr_ba.s_i, ['hi'])
     self.assertEqual(curr_ba.votes['hi'], set([1, 2, 4]))
     self.assertEqual(set([x[0] for x in curr_ba.signatures['hi']]),
                      set([1, 2, 4]))
     self.assertEqual(curr_ba.calculate_votes_for(1), [])
     self.assertEqual(curr_ba.calculate_votes_for(2), [])
     self.assertEqual(curr_ba.calculate_votes_for(3), [])
     self.assertEqual(curr_ba.calculate_votes_for(-1), [])
     self.assertEqual(curr_ba.calculate_votes_for(100), [])
     self.assertEqual(curr_ba.s_i, ['hi'])
     self.assertEqual(curr_ba.votes['hi'], set([1, 2, 4]))
     self.assertEqual(set([x[0] for x in curr_ba.signatures['hi']]),
                      set([1, 2, 4]))
     # single proposal, no votes
     self.reset_ba(curr_ba)
     curr_ba.votes = {"hi": set([])}
     curr_ba.signatures = {"hi": []}
     self.assertEqual(curr_ba.calculate_votes_for(100), [])
     self.assertEqual(curr_ba.calculate_votes_for(0), [])
     # multi proposal, mixed votes
     self.reset_ba(curr_ba)
     curr_ba.votes = {
         "hi": set([1, 2, 3, 4]),
         "a": set([1, 2]),
         "64": set([6])
     }
     curr_ba.signatures = {
         "hi": [(1, "a"), (2, "b"), (3, "c"), (4, "d")],
         "a": [(1, "a"), (2, "b")],
         "64": [6, "z"]
     }
     # ensure data structures are correctly updated
     self.assertEqual(set(curr_ba.calculate_votes_for(0)), set(["hi", "a"]))
     self.assertEqual(set(curr_ba.calculate_votes_for(1)), set([]))
     self.assertEqual(curr_ba.calculate_votes_for(3), [])
     self.assertEqual(curr_ba.calculate_votes_for(10), [])
Example #3
0
    def test_ba_output(self):
        SimplePKIBA.run_protocol_loop = lambda x: x  # disable protocol loop to prevent hanging thread
        curr_ba = SimplePKIBA(1)

        # Check that if done is False, no output is returned regardless of s_i
        # (no matter what, this should be None)
        curr_ba.is_done = lambda: False
        curr_ba.s_i = [1]
        self.assertEqual(curr_ba.get_output(), None)
        curr_ba.s_i = []
        self.assertEqual(curr_ba.get_output(), None)
        curr_ba.s_i = [1, 2]
        self.assertEqual(curr_ba.get_output(), None)

        # Check that if done is True, correct output is returned regardless of s_i
        curr_ba.is_done = lambda: True
        curr_ba.s_i = [1]
        self.assertEqual(curr_ba.get_output(), 1)
        curr_ba.s_i = []
        self.assertEqual(curr_ba.get_output(),
                         0)  # no elements in s_i; output 0
        curr_ba.s_i = [1, 2]
        self.assertEqual(
            curr_ba.get_output(),
            0)  # multiple elements in s_i (Byzantine sender); output 0
Example #4
0
 def test_ba_proposals(self):
     SimplePKIBA.run_protocol_loop = lambda x : x # disable protocol loop to prevent hanging thread
     curr_ba = SimplePKIBA(1)
     import config
     config.node_id = 4
     self.assertEqual(curr_ba.get_proposals_with_threshold(0), [])
     self.assertEqual(curr_ba.get_proposals_with_threshold(1000), [])
     self.assertEqual(curr_ba.get_proposals_with_threshold(-1), [])
     # single proposal, some votes
     curr_ba.votes = {"hi": set([1,2])}
     self.assertEqual(curr_ba.get_proposals_with_threshold(0), ['hi'])
     self.assertEqual(curr_ba.get_proposals_with_threshold(1), ['hi'])
     self.assertEqual(curr_ba.get_proposals_with_threshold(2), ['hi'])
     self.assertEqual(curr_ba.get_proposals_with_threshold(3), [])
     self.assertEqual(curr_ba.get_proposals_with_threshold(-1), ['hi'])
     self.assertEqual(curr_ba.get_proposals_with_threshold(100), [])
     # single proposal, no votes
     curr_ba.votes = {"hi": set([])}
     self.assertEqual(curr_ba.get_proposals_with_threshold(100), [])
     self.assertEqual(curr_ba.get_proposals_with_threshold(0), [])
     # multi proposal, mixed votes
     curr_ba.votes = {"hi": set([1,2,3,4]), "a": set([1,2]), "64": set([6])}
     self.assertEqual(set(curr_ba.get_proposals_with_threshold(0)), set(["hi", "a"]))
     self.assertEqual(set(curr_ba.get_proposals_with_threshold(1)), set(["hi", "a"]))
     self.assertEqual(curr_ba.get_proposals_with_threshold(3), ["hi"])
     self.assertEqual(curr_ba.get_proposals_with_threshold(10), [])