Example #1
0
    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)
Example #2
0
    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))
Example #3
0
    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
Example #4
0
    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()
Example #5
0
    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)
Example #6
0
 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)
Example #7
0
 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
Example #8
0
 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
Example #9
0
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
Example #10
0
    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
Example #11
0
    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))
Example #12
0
 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
Example #13
0
 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
Example #14
0
 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
Example #15
0
    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)