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()
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])
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
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)
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)
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
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
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!")
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)
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)
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)
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
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
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)
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
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()
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']))
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()]
from ballot import Ballot ballot = Ballot()
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
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)
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()]
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)