예제 #1
0
    def calculate_votes_for(self, round):
        """ Calculate what votes a node should gossip out in the provided round.
            These are proposals that match the criteria given in 4.1, and that a
            node has not previously added to its s_i set and broadcast votes for.
            This function should also update the relevant data structures with the
            current node's vote.

            Args:
                round (int): Round to target.

            Returns:
                list of str: Returns a list of proposals to broadcast votes for.
        """
        # Get all proposals with r votes, including sender
        # proposal is new proposal that has just achieved threshold (m not in Sj)
        # Pseudocode: then j adds m to its set Sj, signs m using its secret key skj, and multicasts...

        broadcast_votes_for = []
        for m in self.get_proposals_with_threshold(round):
            if m not in self.s_i:
                self.s_i.append(m)
                self.votes[m].add(config.node_id)
                proposal_sig = util.sign_message(m, config.SECRET_KEYS[config.node_id])
                self.signatures[m].append((config.node_id, proposal_sig))
                broadcast_votes_for.append(m)

        return broadcast_votes_for
예제 #2
0
    def calculate_votes_for(self, round):
        """ Calculate what votes a node should gossip out in the provided round.
            These are proposals that match the criteria given in 4.1, and that a
            node has not previously added to its s_i set and broadcast votes for.
            This function should also update the relevant data structures with the
            current node's vote.

            Args:
                round (int): Round to target.

            Returns:
                list of str: Returns a list of proposals to broadcast votes for.
        """
        # Get all proposals with r votes, including sender
        all_proposals = self.get_proposals_with_threshold(round)
        proposals_broadcast = []
        for prop in all_proposals:
            if prop not in self.s_i:
                self.s_i.append(prop)
                self.votes[prop].add(config.node_id)
                proposal_sig = util.sign_message(prop, config.SECRET_KEYS[config.node_id])
                self.signatures[prop].append([config.node_id, proposal_sig])
                proposals_broadcast.append(prop)

        return proposals_broadcast
예제 #3
0
    def __init__(self, sender):
        """ A simple PKI based protocol for Byzantine agreement.

            Args:
                sender (int): Node ID of sender in peer list.

            Attributes:
                s_i (list of tuples of str): represents accepted proposals.
                votes (map of str to set of int): represents nodes that broadcasted signatures on a message/proposal.
                signatures (map of str to list of (tuple of int, str)): maps string messages/proposals to
                    accepted signatures; each signature is a tuple of the node ID that signed and string hex signature.
                sender (int): node ID acting as the protocol sender (see protocol description in notes)
                curr_round_number (int): last round processed internally by the BA protocol
        """
        # Pseudocode: All players i maintain a set Si (of possible outputs) that starts off as empty
        self.s_i = []
        self.votes = {} # maps proposed messages to sets of node IDs that voted for that message
        self.signatures = {} # maps proposed messages to list of accepted (node_id, signature) tuples, corresponding to valid votes
        self.sender = sender
        self.curr_round_number = -1

        # Player s (the sender) receiving (s; m) as input computes and multicasts mpks, and adds m to his set Ss.
        if config.node_id == sender:
            string_to_vote_for = str(int(random.random() * 2 ** 256)) # for demo purposes, we'll vote for a random string
            self.votes[string_to_vote_for] = set([config.node_id])
            proposal_sig = util.sign_message(string_to_vote_for, config.SECRET_KEYS[config.node_id])
            self.signatures[string_to_vote_for] = [(config.node_id, proposal_sig)]

        self.run_protocol_loop()
예제 #4
0
    def calculate_votes_for(self, round):
        """ Calculate what votes a node should gossip out in the provided round.
            These are proposals that match the criteria given in 4.1, and that a
            node has not previously added to its s_i set and broadcast votes for.
            This function should also update the relevant data structures with the
            current node's vote.

            Args:
                round (int): Round to target.

            Returns:
                list of str: Returns a list of proposals to broadcast votes for.
        """
        # Get all proposals with r votes, including sender
        prop_list = []
        for each_prop in self.votes.keys():
            if each_prop not in self.s_i:
                if len(self.votes[each_prop]) >= round and len(self.votes[each_prop]) != 0 and (1 in self.votes[each_prop]):
                    prop_list.append(each_prop)
                    self.s_i.append(each_prop)
                    self.votes[each_prop].add(config.node_id)
                    self.signatures[each_prop].append((config.node_id, util.sign_message(
                        each_prop, config.SECRET_KEYS[config.node_id])))

        # placeholder for (3.1)
        # proposal is new proposal that has just achieved threshold (m not in Sj)
        # Pseudocode: then j adds m to its set Sj, signs m using its secret key skj, and multicasts...

        return prop_list
예제 #5
0
 def mine(self):
     """ PoA signer; seals a block with new seal data by signing it, checking that
         signature is valid, and returning.
     """
     while not self.seal_is_valid():
         signature = util.sign_message(self.unsealed_header(),
                                       config.AUTHORITY_SK)
         self.set_seal_data(int(signature, 16))