def updateChain(self, ret = True): chainChoice = {} self.updateNeighbours(ret = False) self._neighboursMutex.acquire() for k, v in self.getNeighbours().items(): if v.ping: id = v.id() chain_hash = self.getChainHashOfId(id) if chain_hash: if chain_hash not in chainChoice: chainChoice[chain_hash] = [id, 0] else: chainChoice[chain_hash][1] += 1 node.mutexReleaser(self._neighboursMutex) max_vote = 1 my_id = self.id() max_voted_chain_id = my_id for k, v in chainChoice.items(): if v[1] > max_vote: max_vote = v[1] max_voted_chain_id = v[0] if max_voted_chain_id != my_id: chain = self.getChainOfId(max_voted_chain_id) if chain: self._chainMutex.acquire() pendTransactions = self._chain.pendingTransactions self._chain = blockchain.Blockchain(chain) for k, v in pendTransactions.items(): self._chain.addTransaction(k, v) node.mutexReleaser(self._chainMutex) return ret
def __broadcastBlock(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') id = A.pop('id') if rsa.verify(sig, json.dumps(A, sort_keys=True), A['public key']): A['sig'] = sig for k, v in A['transactions'].items(): if not self.__validateOfficerSignatures(v): f('NOT OK') return self._chainMutex.acquire() ret = self._chain.addBlock(A) node.mutexReleaser(self._chainMutex) if ret: A = dict(A) A['id'] = self.id() f('OK') self.__broadcastUtil(A, 'broadcast_block', id) return except: pass f('NOT OK')
def __broadcastUtil(self, A, cmd, id = None): self.updateNeighbours(False) self._neighboursMutex.acquire() for k, v in self.getNeighbours().items(): v_id = v.id() if v_id != id: B = '{} {}'.format(cmd, json.dumps(A)) v.command(B) node.mutexReleaser(self._neighboursMutex)
def broadcastVote(self, voter_id, party): ret = self.verifyVoterId(voter_id) if not ret[0] or ret[1] == 'ALREADY VOTED': return ret keys = self.getKeys() A = { 'voter id': voter_id, 'random nonce': hashlib.blake2s('{0}{1}{0}'.format(crypto_number.getRandomNumber(RND_SYMM_KEY_SIZE), voter_id).encode('utf-8')).hexdigest() } B = 'verify {}'.format(json.dumps(A, sort_keys = True)) tmp = response_from_blo = self._local.command(B, BLO_ID) try: tmp = response_from_blo = json.loads(response_from_blo) if rsa.verify(response_from_blo, A['random nonce'], BLO_PUBLIC_KEY): try: tmp = response_from_ext_officer = self._local.command(B, EXT_OFFICER_ID) response_from_ext_officer = json.loads(response_from_ext_officer) if rsa.verify(response_from_ext_officer, A['random nonce'], EXT_OFFICER_PUBLIC_KEY): symm_key = crypto_number.getRandomNumber(RND_SYMM_KEY_SIZE) voter_hash = aesHmac.symmEncryption(hashlib.blake2s('{}'.format(voter_id).encode('utf-8')).hexdigest(), symm_key) voter_hash = hashlib.sha256(voter_hash).hexdigest() p1, p2 = self.__nonceifyParty(voter_hash, party) pk, sk = self.getKeys() A = { 'voter': voter_hash, 'party (blo encrypted)': p1, 'party (ext-officer encrypted)': p2, 'timestamp': time.time(), 'public key': pk, 'random nonce': A['random nonce'], 'blo signature': response_from_blo, 'ext-officer signature': response_from_ext_officer } A['sig'] = rsa.sign(json.dumps(A, sort_keys = True), sk) self._chainMutex.acquire() ret = self._chain.addTransaction(voter_hash, A) node.mutexReleaser(self._chainMutex) if ret: A = dict(A) A['id'] = self.id() self.__broadcastUtil(A, 'broadcast_vote') DB_MANAGER = ssql.SSQLiteManager('public_details.db') DB_MANAGER.update('ELIGIBLE_VOTERS', 'status = 0', '"voter id" == "{}"'.format(voter_id)) DB_MANAGER.commit() DB_MANAGER.close() return True, 'BRAVO', symm_key except: return False, 'EXT-OFFICER REJECTED' if tmp == 'NOT OK' else 'EXT-OFFICER NOT AVAILABLE' except: return False, 'BLO REJECTED' if tmp == 'NOT OK' else 'BLO NOT AVAILABLE'
def __getChainHash(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') if rsa.verify(sig, json.dumps(A, sort_keys=True), A['public key']): self._chainMutex.acquire() A = blockchain.hash(self._chain.chain) node.mutexReleaser(self._chainMutex) pk, sk = self.getKeys() A = {'chain hash': A, 'public key': pk} A['sig'] = rsa.sign(json.dumps(A, sort_keys=True), sk) A = json.dumps(A) f(A) return except: pass f('NOT OK')
def __getChain(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') if rsa.verify(sig, json.dumps(A, sort_keys=True), A['public key']): self._chainMutex.acquire() A = dict(self._chain.__dict__) node.mutexReleaser(self._chainMutex) pk, sk = self.getKeys() A.pop('mineableTransactionsMutex') A.pop('pendingTransactionsMutex') A = {'chain': A, 'public key': pk} A['sig'] = rsa.sign(json.dumps(A, sort_keys=True), sk) A = json.dumps(A) f(A) return except: pass f('NOT OK')
def shutdown(self): self.writeChain() try: node.mutexReleaser(self._shutdownMutex) node.mutexReleaser(self._chainMutex) node.mutexReleaser(self._neighboursMutex) self._shutdownMutex.acquire() self._shutdown = True except: pass node.mutexReleaser(self._shutdownMutex) #self.mine(False) try: self._local.shutdown() except: pass
def mine(self, ret = True): if (self._chain.isMineable() and self.isMiner()) or self._chain.gottaMine(): transactions = self._chain.mineableTransactions self._chain.mineableTransactionsMutex.acquire() self._chain.mineableTransactions = {} node.mutexReleaser(self._chain.mineableTransactionsMutex) self._chainMutex.acquire() block = { 'index': len(self._chain.chain) + 1, 'timestamp': time.time(), 'proof': None, 'transactions': transactions, 'total transactions': len(transactions), 'prev hash': blockchain.hash(self._chain.lastBlock) } node.mutexReleaser(self._chainMutex) block['proof'] = blockchain.proofOfWork(self._chain.lastBlock['proof'], block['prev hash']) self._chainMutex.acquire() self._chain.addBlock(block) node.mutexReleaser(self._chainMutex) self.__broadcastBlock(block) return ret
def getTurnout(self): self._chainMutex.acquire() tot_votes_till_now = self._chain.totalTransactionsInChain - 1 node.mutexReleaser(self._chainMutex) return tot_votes_till_now, TOTAL_VOTERS
def updateNeighbours(self, ret = True): self._neighboursMutex.acquire() self._neighbours = self._local.getNeighbours() node.mutexReleaser(self._neighboursMutex) return ret
def __init__(self, password, localAddress, hostAddress = None, bits = RSA_BITS): self._chainMutex = threading.BoundedSemaphore() self._neighboursMutex = threading.BoundedSemaphore() self._shutdownMutex = threading.BoundedSemaphore() self._local = node.Node(password, localAddress, hostAddress, bits) def __getChainHash(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') if rsa.verify(sig, json.dumps(A, sort_keys = True), A['public key']): self._chainMutex.acquire() A = blockchain.hash(self._chain.chain) node.mutexReleaser(self._chainMutex) pk, sk = self.getKeys() A = { 'chain hash': A, 'public key': pk } A['sig'] = rsa.sign(json.dumps(A, sort_keys = True), sk) A = json.dumps(A) f(A) return except: pass f('NOT OK') self._local.registerCommand('get_chain_hash', __getChainHash) def __getChain(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') if rsa.verify(sig, json.dumps(A, sort_keys = True), A['public key']): self._chainMutex.acquire() A = dict(self._chain.__dict__) node.mutexReleaser(self._chainMutex) pk, sk = self.getKeys() A.pop('mineableTransactionsMutex') A.pop('pendingTransactionsMutex') A = { 'chain': A, 'public key': pk } A['sig'] = rsa.sign(json.dumps(A, sort_keys = True), sk) A = json.dumps(A) f(A) return except: pass f('NOT OK') self._local.registerCommand('get_chain', __getChain) def __getPublicKey(request, f): f(json.dumps(self.getKeys()[0])) self._local.registerCommand('get_public_key', __getPublicKey) def __broadcastVote(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') id = A.pop('id') if rsa.verify(sig, json.dumps(A, sort_keys = True), A['public key']): A['sig'] = sig if not self.__validateOfficerSignatures(A): f('NOT OK') return self._chainMutex.acquire() ret = self._chain.addTransaction(A['voter'], A) node.mutexReleaser(self._chainMutex) if ret: A = dict(A) A['id'] = self.id() f('OK') self.__broadcastUtil(A, 'broadcast_vote', id) return except: pass f('NOT OK') self._local.registerCommand('broadcast_vote', __broadcastVote) def __broadcastBlock(request, f): try: A = json.loads(request) if type(A) == dict: sig = A.pop('sig') id = A.pop('id') if rsa.verify(sig, json.dumps(A, sort_keys = True), A['public key']): A['sig'] = sig for k, v in A['transactions'].items(): if not self.__validateOfficerSignatures(v): f('NOT OK') return self._chainMutex.acquire() ret = self._chain.addBlock(A) node.mutexReleaser(self._chainMutex) if ret: A = dict(A) A['id'] = self.id() f('OK') self.__broadcastUtil(A, 'broadcast_block', id) return except: pass f('NOT OK') self._local.registerCommand('broadcast_block', __broadcastBlock) self._local.start() self._isMiner = False self._shutdown = False self._neighbours = {} self._chainMutex.acquire() if not hostAddress: self._chain = blockchain.Blockchain() else: self._chain = blockchain.Blockchain(self.getChainOfId(hostAddress.id())) node.mutexReleaser(self._chainMutex) self._daemon = {} self._daemon['update_neighbours'] = threading.Thread(target = self.updateNeighbours) self._daemon['update_chain'] = threading.Thread(target = self.updateChain) self._daemon['sch_mining'] = threading.Thread(target = self.mine) for k, v in self._daemon.items(): v.daemon = True v.start()