def on_post(self, req, resp): """ Endpoint that client POSTs to, to accept peers that have registered with client but haven't accepted yet (peers with status: 'acceptance-pending') """ peer_addrs = str(tuple(utils.parse_post_req(req)['ips'])).replace( ",)", ")") update_query = "UPDATE peer_addresses SET REGISTRATION_STATUS = 'registered' WHERE REGISTRATION_STATUS = 'acceptance-pending' AND IP IN {}".format( peer_addrs) db_resp = DBService.post("peer_addresses", update_query) if db_resp != True: final_title = 'Error' final_msg = db_resp resp.status = falcon.HTTP_500 else: sql_query = "SELECT IP FROM peer_addresses WHERE REGISTRATION_STATUS = 'registered' AND IP IN {}".format( peer_addrs) res = DBService.query("peer_addresses", sql_query) if res: accepted_peers = res['rows'] ip_query = "SELECT IP FROM node_prefs" my_ip = DBService.query("node_prefs", ip_query)['rows'][0] my_pub_key = Certs().public_key acceptance_msg = { 'registrar_ip': '{}'.format(my_ip), 'registration_status': 'Success', 'public_key': my_pub_key } for peer in accepted_peers: url = 'http://{}:4200/update-registration-status'.format( peer) try: peer_resp = requests.post( url, data=json.dumps(acceptance_msg)) except requests.exceptions.RequestException as e: err_msg = 'Peer not reachable' print('**{}\n**{}\n**{}'.format(err_msg, peer, e)) utils.notifier("peer_not_reachable", {'peer_ip': peer}) final_title = 'Success' final_msg = 'Accepted Peer(s): {}'.format(accepted_peers) resp.status = falcon.HTTP_201 peer = {'peer_ip': accepted_peers[0], 'status': 'registered'} utils.notifier("accepted_peer", {'peer_ip': accepted_peers[0]}) else: final_title = 'Error' final_msg = "Can only accept peers that exist in DB with status: 'acceptance-pending'." resp.status = falcon.HTTP_400 msg = {'Title': final_title, 'Message': final_msg} resp.content_type = 'application/json' resp.body = json.dumps(msg)
def on_post(self, req, resp): peer_addr = str(utils.parse_post_req(req)['ip']) sql_query = "SELECT REGISTRATION_STATUS FROM peer_addresses WHERE IP = '{}'".format( peer_addr) res = DBService.query("peer_addresses", sql_query) print(res) if res: peer_status = str(res['rows'][0]) print(peer_status) if peer_status == "registered": final_title = 'Success' final_msg = 'Okay. Attempting to send you my Info.' resp.status = falcon.HTTP_200 ip_query = "SELECT IP FROM node_prefs" my_ip = DBService.query("node_prefs", ip_query)['rows'][0] my_pub_key = Certs().public_key acceptance_msg = { 'registrar_ip': '{}'.format(my_ip), 'registration_status': 'Success', 'public_key': my_pub_key } url = 'http://{}:4200/update-registration-status'.format( peer_addr) try: peer_resp = requests.post(url, data=json.dumps(acceptance_msg)) except requests.exceptions.RequestException as e: err_msg = 'Peer not reachable' print('**{}\n**{}\n**{}'.format(err_msg, peer, e)) utils.notifier("peer_not_reachable", {'peer_ip': peer_addr}) elif peer_status == "acceptance-pending": final_title = 'In Progress' final_msg = 'You are yet to be accepted.' resp.status = falcon.HTTP_202 else: final_title = 'Error' final_msg = 'Something is not right!' resp.status = falcon.HTTP_500 else: final_title = 'Error' final_msg = 'Unauthorized. You seem like a fishy person!' resp.status = falcon.HTTP_401 msg = {'title': str(final_title), 'message': str(final_msg)} resp.content_type = 'application/json' resp.body = json.dumps(dict(msg))
def get_prev_block_hash(self): if self.prev_block_hash != None: return self.prev_block_hash def _using_block_num(): if self.block_num != None: if self.block_num - 1 < 1: return '0' else: prev_block_num = self.block_num - 1 sql_query = "SELECT BLOCK_HASH FROM main_chain WHERE BLOCK_NUM = {}".format( prev_block_num) res = DBService.query("main_chain", sql_query) prev_hash = False if not res else '{}'.format( res['rows'][0]) return prev_hash else: return False prev_hash = _using_block_num() if prev_hash != True: if self.block_hash != None: sql_query = "SELECT BLOCK_NUM FROM main_chain WHERE BLOCK_HASH = '{}'".format( self.block_hash) res = DBService.query("main_chain", sql_query) self.block_num = None if not res else res['rows'][0] prev_hash = _using_block_num() self.prev_block_hash = prev_hash if prev_hash else None return self.prev_block_hash
def populate_my_prefs(self): """ Populate my_prefs db if its empty or the info in config file doesn't match the db data. """ sql_query = "SELECT * FROM node_prefs" res = DBService.query("node_prefs", sql_query) try: my_ip = socket.gethostbyname(socket.gethostname()) except: my_ip = socket.gethostname() vals = (self.config['UUID'], my_ip, self.config['MY_PREFERENCES']) def _insert_config_info(): insert_sql = DBService.insert_into("node_prefs", vals) DBService.post("node_prefs", insert_sql) if not res: # If no info in DB _insert_config_info() elif tuple(res['rows'][0]) != vals: # If info doesnt match delete_sql = "DELETE FROM node_prefs WHERE IP='{}'".format(my_ip) DBService.post("node_prefs", delete_sql) _insert_config_info()
def populate_peer_addresses(self): """ Populate the peer_addresses db if empty """ sql_query = "SELECT count(*) FROM peer_addresses" res = DBService.query("peer_addresses", sql_query) num_addrs = res['rows'][0] my_ip = str( DBService.query("node_prefs", "SELECT IP FROM node_prefs")['rows'][0]) core_peer_ip = str(self.config['CORE_PEER']['IP']) if not num_addrs > 0 and core_peer_ip != my_ip: vals = (core_peer_ip, 'unregistered', 'unregistered') core_peer_insert_sql = DBService.insert_into( "peer_addresses", vals) post_res = DBService.post("peer_addresses", core_peer_insert_sql)
def on_get(self, req, resp): sql_query = "SELECT * FROM unconfirmed_pool" result = DBService.query("unconfirmed_pool", sql_query) unconfirmed_txns = [ dict(zip(result['column_names'], txn)) for txn in result['rows'] ] if result else [] response = {'unconfirmed_txns': unconfirmed_txns} resp.content_type = 'application/json' resp.status = falcon.HTTP_200 resp.body = json.dumps(response)
def get_block_confirmed_txns(self): sql_query = """ SELECT TXN_HASH, TXN_TIME_STAMP, sender, receiver, amount FROM confirmed_txns WHERE BLOCK_HASH = '{}' """.format(self.block_hash) res = DBService.query("main_chain", sql_query) if res: self.txn_recs = self.convert_to_txns_obj(res) self.txn_hashes = self.gen_txn_hashes() return self.txn_recs else: return False
def _using_block_num(): if self.block_num != None: if self.block_num - 1 < 1: return '0' else: prev_block_num = self.block_num - 1 sql_query = "SELECT BLOCK_HASH FROM main_chain WHERE BLOCK_NUM = {}".format( prev_block_num) res = DBService.query("main_chain", sql_query) prev_hash = False if not res else '{}'.format( res['rows'][0]) return prev_hash else: return False
def broadcast(payload, endpoint, request, isFile=False): """ TODO: • Make Async • Handle when peer doesn't respond (and show error message accordingly - 404 maybe) • Separate 'POST' and 'GET' (broadcast should be only for Posting stuff to everyone) """ my_ip = str(socket.gethostbyname(socket.gethostname())) sql_query = "SELECT IP FROM peer_addresses WHERE IP!='{}' AND REGISTRATION_STATUS='registered'".format( my_ip) query_result = DBService.query("peer_addresses", sql_query) if not query_result: # if 0 results for registered peers addrs returned response = 'No registered peers found. Please add peers and/or register with them.' return response else: ips = query_result['rows'] peer_nodes = list(map(lambda i: 'http://{}:4200/'.format(i), ips)) responses = list() if request == 'POST': responses = list() for peer in peer_nodes: url = peer + endpoint resp = requests.post(url, data=json.dumps(payload)) waw = resp.json() responses.append({'Peer': '{}'.format(peer), 'Response': waw}) return responses elif request == 'GET': responses = [] for peer in peer_nodes: url = peer + endpoint peer_name = urlparse(peer).hostname if isFile: resp = requests.get(url, stream=True) responses.append({ 'Peer': '{}'.format(peer_name), 'Response': resp }) else: resp = requests.get(url) responses.append({ 'Peer': '{}'.format(peer_name), 'Response': resp.json() }) return responses
def _chain(self): sql_query = "SELECT * FROM main_chain" result = DBService.query("main_chain", sql_query) blocks = [ dict(zip(result['column_names'], bloc)) for bloc in result['rows'] ] if result else [] def _bloc(b): bloc = Block(block_num=b['BLOCK_NUM'], block_hash=b['BLOCK_HASH'], nonce=b['NONCE'], time_stamp=b['TIME_STAMP']) bloc.get_block_confirmed_txns() return bloc blocks = list(map(_bloc, blocks)) return blocks
def on_get(self, req, resp): sql_query = "SELECT * FROM peer_addresses" results = DBService.query("peer_addresses", sql_query) if results: res_formatted = list( map( lambda i: { 'peer_ip': i[0], 'pub_key': i[1], 'status': i[2] }, results['rows'])) final_msg = {'peers': res_formatted} else: final_msg = {'Message': 'Zero peers found.', 'peers': []} resp.content_type = 'application/json' resp.status = falcon.HTTP_200 resp.body = json.dumps(dict(final_msg))
def get_txn_recs(self): if self.txn_recs is None: hashes = str(tuple(self.txn_hashes)).replace(",)", ")") sql_query = """ SELECT TXN_HASH, TXN_TIME_STAMP, sender, receiver, amount FROM unconfirmed_pool WHERE TXN_HASH IN {} """.format(hashes) res = DBService.query("unconfirmed_pool", sql_query) if res: txn_recs = self.convert_to_txns_obj(res) if len(txn_recs) != len(self.txn_hashes): return False else: self.txn_recs = self.convert_to_txns_obj(res) return self.txn_recs else: return False else: if len(self.txn_recs) != len(self.txn_hashes): return False return self.txn_recs
def used_nonces(self): sql_query = "SELECT NONCE FROM main_chain" result = DBService.query("main_chain", sql_query) nonces = result['rows'] if result else [] return nonces
def get_block_num(self): sql_query = "SELECT BLOCK_NUM FROM main_chain WHERE BLOCK_HASH='{}'".format( self.block_hash) res = DBService.query("main_chain", sql_query) self.block_num = None if not res else res['rows'][0] return self.block_num
def on_post(self, req, resp): parsed = utils.parse_post_req(req) peer_ip = parsed['peer_ip'][0] ip_query = "SELECT IP FROM node_prefs" my_ip = str(DBService.query("node_prefs", ip_query)['rows'][0]) my_pub_key = str(Certs().public_key) payload_to_send_peers = {'ip': str(my_ip), 'pub_key': str(my_pub_key)} sql_query = "SELECT * FROM peer_addresses WHERE IP='{}'".format( peer_ip) query_result = DBService.query("peer_addresses", sql_query) #Given IP has not been added to DB yet if not query_result: utils.notifier("no_such_peer_in_db", {'peer_ip': peer_ip}) final_title, final_msg = "Fail", "Peer '{}' not found in DB.".format( peer_ip) msg = {'title': final_title, 'message': final_msg} resp.content_type = 'application/json' resp.status = falcon.HTTP_404 resp.body = json.dumps(msg) else: peer_url = url = 'http://{}:4200/new-registration'.format(peer_ip) json_resp = dict() try: peer_resp = requests.post( peer_url, data=json.dumps(payload_to_send_peers)) json_resp = peer_resp.json() except requests.exceptions.RequestException as e: json_resp['title'] = 'Peer not reachable' print('**{}\n**{}\n**{}'.format(json_resp['title'], peer, e)) if json_resp['title'] == "Success: Successfully Added": update_query = "UPDATE peer_addresses SET PUBLIC_KEY = 'unreceived', REGISTRATION_STATUS = 'registration-pending' WHERE IP = '{}'".format( peer_ip) DBService.post("peer_addresses", update_query) utils.notifier("registered_with_new_peer", {'peer_ip': peer_ip}) final_title, final_msg = "Success", "You have registered with {}".format( peer_ip) msg = {'title': final_title, 'message': final_msg} resp.content_type = 'application/json' resp.status = falcon.HTTP_200 resp.body = json.dumps(msg) elif json_resp['title'] == "Success: Successfully Registered": update_url = 'http://{}:4200/request-registration-update'.format( peer_ip) update_resp = dict() my_ip_payload = dict({'ip': my_ip}) utils.notifier("registration_success_waiting_for_handshake", {'peer_ip': peer_ip}) try: peer_update_resp = requests.post( update_url, data=json.dumps(my_ip_payload)) update_resp = peer_update_resp.json() except requests.exceptions.RequestException as e: update_resp['title'] = 'Peer not reachable' print('**{}\n**{}\n**{}'.format(update_resp['title'], peer_ip, e)) utils.notifier("peer_not_reachable", {'peer_ip': peer_ip}) if update_resp['title'] == "Success": utils.notifier("registered_with_new_peer", {'peer_ip': peer_ip}) final_title, final_msg = "Success", "You are registered with {}".format( peer_ip) msg = {'title': final_title, 'message': final_msg} resp.content_type = 'application/json' resp.status = falcon.HTTP_200 resp.body = json.dumps(msg) else: final_title, final_msg = "Fail", { "peer": peer_ip, "response": update_resp } msg = {'title': final_title, 'message': final_msg} resp.content_type = 'application/json' resp.status = falcon.HTTP_404 resp.body = json.dumps(msg) else: utils.notifier("registration_failed", {'peer_ip': peer_ip}) final_title, final_msg = "Fail", { "peer": peer_ip, "response": json_resp } msg = {'title': final_title, 'message': final_msg} resp.content_type = 'application/json' resp.status = falcon.HTTP_403 resp.body = json.dumps(msg)