示例#1
0
文件: node.py 项目: JBrownie77/cs271
    def initPaxos(self, round = None, value = None, ballot = None):
        if round == None:
            round = self.getNextRound()
            
        if ballot == None:
            ballot = Ballot(self.addr[0], self.addr[1])
            if round in self.paxosStates:
                print '{0}: Found a previous ballot for this round. Setting current ballot greater than prev ballot.'.format(self.addr)
                ballot.set_n(self.paxosStates[round].highestBallot.n+1)

        self.lockValue = value

        prop_msg = Message(round, Message.PROPOSER_PREPARE, self.addr, ballot)
        
        print '{0}: Initiating Paxos for round {1}'.format(self.addr, round)
        self.paxosStates[round] = PaxosState(round, PaxosRole.PROPOSER, 
                                             PaxosState.PROPOSER_SENT_PROPOSAL,  
                                             ballot,
                                             value, 
                                             {'promise_quorum_servers':Set()})

        for server in self.getQuorum():
            self.sendMessage(prop_msg, server)
            if 'promise_quorum_servers' in self.paxosStates[round].metadata:
                self.paxosStates[round].metadata['promise_quorum_servers'].add(server)
            else:
                self.paxosStates[round].metadata['promise_quorum_servers'] = Set([server])
                
        t = threading.Thread(name='promise_thread', 
                             target=self.extendPromiseQuorum, 
                             args=[round, prop_msg, 5])
        t.start()
示例#2
0
文件: node.py 项目: krthk/PaxosC
    def initPaxos(self, r = None, value = None, ballot = None):
        if r == None:
            r = self.getNextRound()
            
        if ballot == None:
            ballot = Ballot(self.addr[0], self.addr[1])
            if r in self.paxosStates:
                print '{0}: Found a previous ballot for this r. Setting current ballot greater than prev ballot.'.format(self.addr)
                ballot.set_n(self.paxosStates[r].highestBallot.n+1)

        self.lockValue = value

        prop_msg = Message(r, Message.PROPOSER_PREPARE, self.addr, ballot)
        
        print '{0}: Initiating Paxos for round {1}'.format(self.addr, r)
        self.paxosStates[r] = PaxosState(r, PaxosRole.PROPOSER, 
                                         PaxosState.PROPOSER_SENT_PROPOSAL,  
                                         ballot,
                                         value, 
                                         {'promise_quorum_servers':Set()})

        for server in self.serverSet:
            self.sendMessage(prop_msg, server)
            if 'promise_quorum_servers' in self.paxosStates[r].metadata:
                self.paxosStates[r].metadata['promise_quorum_servers'].add(server)
            else:
                self.paxosStates[r].metadata['promise_quorum_servers'] = Set([server])
示例#3
0
 def updateDepth(self, newDepth):
     self.depth = newDepth
     self.ballotNum = Ballot(self.ballotNum.seqNum, self.ballotNum.procId,
                             self.depth)
     self.acceptBal = Ballot(self.ballotNum.seqNum, self.ballotNum.procId,
                             self.depth)
     self.acceptVal = None
     self.accepts = 0
示例#4
0
 def __init__(self, sockets, myId, onDecision, onAccept):
     self.onDecison = onDecision
     self.onAccept = onAccept
     self.myId = str(myId)
     self.ballotNum = Ballot(0, self.myId, 0)
     self.acceptBal = Ballot(0, self.myId, 0)
     self.acceptVal = None
     self.sockets = sockets
     self.lock = threading.Lock()
     self.depthLock = threading.Lock()
    def verify_submission(submission, get_balance, check_funds=True):
        """Verify a submission by checking whether the voter has the right.

        Arguments:
            :submission: The submission that should be verified.
        """
        if check_funds:
            voter_balance = get_balance(submission.voter)
            return (voter_balance >= submission.amount and
                    Ballot.verify_submission(submission))
        else:
            return Ballot.verify_submission(submission)
示例#6
0
    def readBallots(self):
        for ballotCounter in range(self.numOfBallots):
            ballotChoices = self.fileHandler.readLine().strip().split(",")
            for x in range(len(ballotChoices)):
                if ballotChoices[x] == "":
                    ballotChoices[x] = None
                else:
                    ballotChoices[x] = int(ballotChoices[x])

            ballotInstance = Ballot(ballotCounter, ballotChoices)
            self.ballots[ballotCounter] = ballotInstance
            ballotWinner = ballotInstance.getChoice(1, self.candidateNames)
            self.candidates[ballotWinner].getVote(ballotInstance.bNum)
            print("Ballot #", ballotCounter, "is assigned to", ballotWinner)
示例#7
0
    def from_json(cls, filepath):
        """Instantiates an Election with candidates and ballots loaded from a
        local JSON file."""
        with open(filepath) as file:
            filecontents = file.read()
        data = json.loads(filecontents)

        date     = data['date']
        type     = data['type']
        name     = data['name']
        enrolled = data['enrolled']
        turnout  = len(data['ballots']) # Number of votes received

        election = Election(date, type, name, enrolled, turnout)

        for candidate_dict in data['candidates']:
            candidate = Candidate(
                candidate_dict['id'],
                candidate_dict['name'],
                candidate_dict['party']
            )
            election.candidates.append(candidate)

        for preferences_list in data['ballots']:
            election.ballots.append(Ballot(preferences_list))

        return election
示例#8
0
    def random(cls,
               num_voters: int,
               num_alternatives: int,
               num_groups: int = None) -> 'Profile':
        """Generate a random profile with the given number of voters and alternatives.
        If the num_groups parameter is given, that number of different preferences will be generated
        and assigned to equal groups.
        """

        if num_groups == None:
            num_groups = num_voters

        alternatives = set(
            [chr(c) for c in range(ord('a'),
                                   ord('a') + num_alternatives)])
        ballots = {}
        group_ballots = {}

        for group in [g + 1 for g in range(num_groups)]:
            group_ballots[group] = random.sample(alternatives,
                                                 num_alternatives)

        for voter in [v + 1 for v in range(num_voters)]:
            preference = group_ballots[(voter - 1) % num_groups + 1]
            ballots[voter] = Ballot(id=voter, preference=preference)

        random_profile = cls(ballots, alternatives)
        random_profile.__validate()

        return random_profile
示例#9
0
    async def cast(self, ctx: Context, votename: str):
        if not dm.vote_exists(votename):
            await ctx.send("Vote doesn't exist!")
            return
        self._ensure_user_exists(ctx.author)
        vote = dm.lookup_vote_by_votename(votename)
        msg = f"Please chose the order in which you want to vote for {vote.name}:\n\n"
        for i, option in enumerate(vote, start=1):
            msg+=f"{i}.- {option}\n"
        await ctx.send(msg)

        def check(m):
            if not (m.content.replace(" ","").isnumeric()
            and m.channel == ctx.channel
            and m.author == ctx.author):
                return False
            numlist = list(map(int, m.content.split()))
            unique = bool(len(numlist) == len(set(numlist)))
            return (unique and len(numlist) <= len(vote)
            and max(numlist) <= len(vote))

        try:
            ranks = await self.bot.wait_for("message", timeout=60, check=check)
        except asyncio.TimeoutError:
            await ctx.send("Timed out")
            return
        
        ranklist = list(map(int, ranks.content.split()))
        dm.cast_vote(Ballot(str(ctx.author.id), votename, ranklist))
        await ctx.send("Voted sucessfully!")
示例#10
0
 def _create_ballot(self,
                    candidate_rankings: List[CandidateRanking]) -> Ballot:
     rankings = {
         candidate_ranking.name: int(candidate_ranking.ranking)
         for candidate_ranking in candidate_rankings
         if self._is_valid(candidate_ranking)
     }
     return Ballot(rankings)
示例#11
0
def client(config, voter_keys, index):
    ballots = []
    for i in range(12):
        ballots.append(Ballot(config))
        print("Thread {} registering ballot {}".format(index, i))
        ballots[i].register()
        voter_keys.append(ballots[i].public_hex)

    for i in range(len(ballots)):
        print("Thread {} ballot {} votes for {}".format(index, i, 0))
        ballots[i].vote(ballots[0].public)
示例#12
0
    def receivePromise(self, msg=None, proposalVal=None, timestamp=None):
        #print("Receiving Promise", flush=True)
        if proposalVal is None:
            self.promises.append((msg['acceptBal'], msg['acceptVal']))

        if len(self.promises) == QUORUM_SIZE or self.isLeader:
            if self.isLeader:
                opTime = timestamp
                self.proposalVal = proposalVal
                print(
                    "Already Leader. Starting Paxos from phase II -- Broadcasting ACCEPT.",
                    flush=True)
                self.ballotNum = Ballot(self.ballotNum.seqNum + 1, self.myId,
                                        self.depth)
            else:
                opTime = msg['timestamp']
                print("Received PROMISE from majority -- Broadcasting ACCEPT",
                      flush=True)
                maxBallot = Ballot(0, self.myId, self.depth)
                for ballot, operation in self.promises:
                    if operation is not None and ballot != Ballot(
                            0, self.myId, self.depth) and maxBallot < ballot:
                        self.proposalVal = operation
                        maxBallot = ballot
            msg = {
                'type': 'ACCEPT',
                'ballot': self.ballotNum,
                'operation': self.proposalVal,
                'timestamp': opTime
            }
            for x in range(1, NUM_OF_SERVERS + 1):
                if (str(x) != self.myId):
                    print("sending ACCEPT to server " + str(x))
                    sendMessage(self.myId, str(x), msg, self.sockets,
                                self.activeLinks)
                else:
                    self.receiveAccept(msg)
示例#13
0
    def from_soc(cls, path: str) -> 'Profile':
        """Imports a `.soc` file from PrefLib representing a complete strict order
        """

        ballots = {}
        alternatives = set()
        alternative_names = {}

        with open(path) as socfile:
            reader = socfile.readlines()

            cur_line = 0

            # read alternatives
            num_alternatives = int(reader[cur_line])
            cur_line += 1

            for alternative in range(cur_line, cur_line + num_alternatives):
                alternative_line = reader[alternative].split(",")
                alternative_id = alternative_line[0].strip()
                alternative_name = alternative_line[1].strip()

                alternatives.add(alternative_id)
                alternative_names[alternative_id] = alternative_name
                cur_line += 1

            # read info
            info = reader[cur_line].split(",")
            total_votes = int(info[0])
            unknown_1 = int(info[1])
            num_unique_ballots = int(info[2])
            cur_line += 1

            # read profile
            for ballot in range(cur_line, cur_line + num_unique_ballots):
                ballot_line = reader[ballot].split(",", maxsplit=1)
                ballot_id = ballot - cur_line + 1
                ballot_weight = int(ballot_line[0])
                ballot_preference = ballot_line[1].strip().split(",")
                ballot = Ballot(id=ballot_id,
                                preference=ballot_preference,
                                weight=ballot_weight)
                ballots[ballot_id] = ballot

        new_profile = cls(ballots, alternatives, alternative_names)
        new_profile.__validate()

        return new_profile
示例#14
0
    def from_csv(cls, path: str) -> 'Profile':
        """Converts a csv file containing a profile to a Profile object.
        Expects voter ids as column names and preferences as columns, e.g.:

        ```
        1, 2, 3
        a, c, a
        b, a, c
        c, b, b
        ```

        You can imagine this as a profile, but rotated by 90° clockwise.
        Whitespace is ignored.

        Returns:
            Profile: A profile object.
        """
        ballots = {}
        alternatives = set()

        with open(path) as csvfile:
            reader = csv.DictReader(csvfile,
                                    delimiter=",",
                                    skipinitialspace=True,
                                    quoting=csv.QUOTE_MINIMAL)

            for voter in reader.fieldnames:
                voter_id = int(voter)
                # note: the Ballot constructor has a default value of [] for
                # its preference field, but not initialising it breaks the
                # program; all ballots then reference the same list. (???)
                ballots[voter_id] = Ballot(id=voter_id, preference=[])

            for line in reader:
                for voter in reader.fieldnames:
                    ballots[int(voter)].preference.append(line[voter])

        new_profile = cls(ballots, alternatives)

        # This will raise an error if the profile is invalid
        new_profile.__validate()

        return new_profile
示例#15
0
    def prepareProposal(self, operation, timestamp):
        print("Starting Leader Election -- Broadcasting PREPARE", flush=True)
        self.isLeader = False
        self.ballotNum = Ballot(self.ballotNum.seqNum + 1, self.myId,
                                self.depth)
        self.proposalVal = operation
        self.promises = []
        self.accepts = 0
        self.isAccepted = True  #If we are a leader and we get a request to accept we deny because we accept our value
        msg = {
            'type': 'PREPARE',
            'ballot': self.ballotNum,
            'timestamp': timestamp
        }
        for x in range(1, NUM_OF_SERVERS + 1):
            if (str(x) != self.myId):
                sendMessage(self.myId, str(x), msg, self.sockets,
                            self.activeLinks)
        #leader is part of quorum and needs to "receive" the message

        self.receivePrepares(msg)
示例#16
0
    def from_txt(cls, path: str) -> 'Profile':
        """Converts a file containing a profile to a Profile object.
        Expects the following format:

        ```
        1: a b c
        2: c b a
        3: a c b
        ```

        Whitespace is ignored.

        Returns:
            Profile: A profile object.
        """

        ballots = {}
        alternatives = set()

        with open(path) as txtfile:
            reader = txtfile.readlines()

            # save set of alternatives
            alternatives.update(reader[0].split(":")[1].split())

            # save voter preferences
            for voter in reader:
                split = voter.split(":", 1)
                voter_id = int(split[0])
                preference = split[1].split()
                ballots[voter_id] = Ballot(id=voter_id, preference=preference)

        # use constructor to create a profile
        new_profile = cls(ballots, alternatives)
        # This will raise an error if the profile is invalid
        new_profile.__validate()

        return new_profile
示例#17
0
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.serialization import load_pem_public_key

NUM_VOTERS = 10
config = {}
config['issuer_address'] = 'http://localhost:12345/ISSUER'
# config['node_addresses'] = ["http://localhost:30001/PROCESSOR", "http://localhost:30002/PROCESSOR", "http://localhost:30003/PROCESSOR"]
config['node_addresses'] = ["http://localhost:30001/PROCESSOR"]


issuer = xmlrpc.client.ServerProxy(config['issuer_address'])
processor = xmlrpc.client.ServerProxy(config['node_addresses'][0])

print('Election has started: ', issuer.start_election())

Ralph = Ballot(config)
David = Ballot(config)
Billy = Ballot(config)
print('David registering to Vote: ', David.register())
print('Ralph registering to Vote: ', Ralph.register())
voters = []
voter_threads = []
# multi threaded registration
for i in range(NUM_VOTERS):
	voters.append(Ballot(config))
	voter_threads.append(threading.Thread(target=voters[i].register, args=()))
	voter_threads[i].start()

# wait for all the voting to be done
for i in range(NUM_VOTERS):
	voter_threads[i].join()
示例#18
0
NUM_VOTERS = issuer.get_transactions_per_block() * 5
try:
    print('Starting the election by sending the issuers public key:',
          issuer.start_election())
except:
    print('The Issuer is not up')
    exit()
print('The number of transactions per block is ',
      issuer.get_transactions_per_block(),
      '. Thus transactions will be verified after every ',
      issuer.get_transactions_per_block(), ' transsactions are posted.')
print('First we register ', str(NUM_VOTERS),
      ' Voters where each registration is a separate transaction.')
ballots = []
for i in range(NUM_VOTERS):
    ballots.append(Ballot(config))
    print("Registering ballot: ", ballots[i].register())
print(
    "Now for each registered ballot we check the wallet balance to verify that they are actually registered. Each should be 1."
)
for i in range(NUM_VOTERS):
    print('Voter', str(i), ' balance is: ', ballots[i].tally())
# for node_address in config['node_addresses']:
# 	issuer.set_nodes(pickle.dumps([node_address]))
# 	try:
# 		print_processor_wallets(issuer, ballots)
# 	except:
# 		print('Probably a key error')
# 	break
# issuer.set_nodes(pickle.dumps(config['node_addresses']))
示例#19
0
def lookup_ballots_by_user(userid: str) -> List[Ballot]:
    with DBCursor(database) as c:
        c.execute('SELECT * FROM ballots WHERE userid = ?', (userid, ))
        return [Ballot.from_database(elem) for elem in c.fetchall()]
示例#20
0
from ballot import Ballot

ballot = Ballot()
示例#21
0
    def mine_bloc(self):
        global VOTE_WINDOW
        """Create a new bloc and add open submissions to it."""
        # update your ip (only if your publickey is registered) so that mining can be shared with all nodes
        if self.public_key is None:
            return None

        publickey = {"publickey": self.public_key}
        requests.post('https://blocbit.net/kitty.php' ,params=publickey)
        # Fetch the currently last bloc of the blocchain
        last_bloc = self.__chain[-1]
        #last_pf = last_bloc.proof
        #window = self.load_window_data()
        # Hash the last bloc (=> to be able to compare it to the stored hash
        # value)
        hashed_bloc = hash_bloc(last_bloc)
        proof = self.proof_by_vote()
        # Added to avoid blocchain startup error after genesis bloxk as it contains no submission i.e. no zero
        # last_pf = last_bloc.proof
        # if last_pf != 86400:
        #     zero = self.submission_zero()           
        # else:
        #     zero = 365.0
        zero = self.submission_zero()
        # Voters have the right to vote daily, so let's create a window submission
        # reward_submission = {
        #     'voter': 'STATION',
        #     'candidate': owner,
        #     'amount': 0 or 1
        # }
        Station_open = Submission(
            'STATION', self.public_key, zero, '', 1)
        Station_closed = Submission(
            'STATION', self.public_key, zero, '', 0)
        # Copy submission instead of manipulating the original
        # open_submissions list
        # This ensures that if for some reason the mining should fail,
        # we don't have the reward submission stored in the open submissions
        copied_submissions = self.__open_submissions[:]
        for tx in copied_submissions:
            if not Ballot.verify_submission(tx):
                return None
        
        # if global var is set to true award right and then set back to false
        if VOTE_WINDOW is False:
            copied_submissions.append(Station_closed)
        else:
            copied_submissions.append(Station_open)
            VOTE_WINDOW = False
        bloc = Bloc(len(self.__chain), hashed_bloc,
                      copied_submissions, proof)
        self.__chain.append(bloc)
        self.__open_submissions = []
        self.save_data()
        for node in self.__peer_nodes:
            url = 'http://{}/broadcast-bloc'.format(node)
            converted_bloc = bloc.__dict__.copy()
            converted_bloc['submissions'] = [
                tx.__dict__ for tx in converted_bloc['submissions']]
            try:
                response = requests.post(url, json={'bloc': converted_bloc})
                if response.status_code == 400 or response.status_code == 500:
                    print('Bloc declined, needs resolving')
                if response.status_code == 409:
                    self.resolve_conflicts = True
            except requests.exceptions.ConnectionError:
                continue
        return bloc
示例#22
0
    blocchain.remove_peer_node(node_url)
    response = {
        'message': 'Node removed',
        'all_nodes': blocchain.get_peer_nodes()
    }
    return jsonify(response), 200


@app.route('/nodes', methods=['GET'])
def get_nodes():
    nodes = blocchain.get_peer_nodes()
    response = {
        'all_nodes': nodes
    }
    return jsonify(response), 200


if __name__ == '__main__':
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', type=int, default=8105)
    args = parser.parse_args()
    port = args.port
    ballot = Ballot(port)
    blocchain = Blocchain(ballot.public_key, port)

    blocchain.add_peer_node('https://explorer.blocbit.net')


    app.run(host='0.0.0.0', port=port)
示例#23
0
def lookup_ballots_by_vote(votename: str) -> List[Ballot]:
    with DBCursor(database) as c:
        c.execute('SELECT * FROM ballots WHERE votename = ?', (votename, ))
        return [Ballot.from_database(elem) for elem in c.fetchall()]
示例#24
0
 def initialize_election(self, file_name):
     election_info = self.read_election_info(file_name)
     for ballot_info in election_info:
         new_ballot = Ballot(ballot_info.split())
         self.electoral_system.register_ballot(new_ballot)