def register_node(self, address, ASN): """ Add a new node to the list of nodes in the blockchain network. Also updates the ASN Nodes list. :param address: <str> Address of node. E.g., 'http://192.168.0.5:5000' :param ASN: <str> AS number of the node :return: None """ parsed_url = urlparse(address) bc_nodes_mutex.acquire() self.nodes.add((parsed_url.scheme + "://" + parsed_url.netloc, ASN)) bc_nodes_mutex.release() ip_port_list = parsed_url.netloc.split(":") ip_addr = ip_port_list[0] port = int(ip_port_list[1]) found_it = 0 asn_nodes_mutex.acquire() for asn in ASN_nodes: if ip_addr in asn and port == asn[1]: found_it = 1 break asn_nodes_mutex.release() if not found_it: ASN_nodes.append([ip_addr, port, ASN, None])
def check_alive(): """ Checks if the neighbors are still here. Removes the dead neighbors from the neighbors set. """ bc_nodes_mutex.acquire() neighbors = blockchain.nodes.copy() bc_nodes_mutex.release() dead_neighbors = [] for node in neighbors: try: url = node[0] AN_mutex.acquire() last_alive = alive_neighbors[url] AN_mutex.release() time_now = time() if time_now - last_alive > 60: dead_neighbors.append(node) except KeyError: # node was already removed, do nothing AN_mutex.release() for node in dead_neighbors: neighbors.remove(node) AN_mutex.acquire() alive_neighbors.pop(node[0]) asn_nodes_mutex.acquire() remove_from_ASN_Nodes(node[0]) asn_nodes_mutex.release() AN_mutex.release() # start a timer that calls this function every 60 seconds. threading.Timer(60.0, check_alive).start()
def receive_incoming_public_key(): """ A node receives a public key, the IP Address and Port from another node. Updates the ASN Nodes list. """ values = request.get_json() # Check that required fields are in the posted data required = ['public_key', 'IPAddress', 'Port', 'ASN'] if not all(k in values for k in required): return 'Missing values', 400 ip = values['IPAddress'] port = values['Port'] asn = values['ASN'] public_key = values['public_key'] found = 0 asn_nodes_mutex.acquire() for AS in ASN_nodes: if ip in AS and int(port) == AS[1]: found = 1 break asn_nodes_mutex.release() if found == 0: ASN_nodes.append([ip, int(port), asn, None]) addr = "http://" + ip + ":" + str(port) blockchain.register_node(addr, asn) update_nodes_publicKey(public_key, ip, port) return "Received a public key.", 200
def find_asn_public_key(self): """ Finds the public key of the AS node that made this transaction. :return: <RSA key> The public key of the node, or None if the key is not found. """ ASN_pkey = None asn_nodes_mutex.acquire() for asn in ASN_nodes: # find ASN public key if self.as_source == asn[2]: ASN_pkey = asn[-1] break asn_nodes_mutex.release() return ASN_pkey
def check_as(self): """ Checks if the destination ASes of an IP Assign transaction are in the blockchain network. :return: <bool> True if the ASes are in the network, False otherwise. """ ASes = [] asn_nodes_mutex.acquire() for i in range(len(ASN_nodes)): ASes.append(ASN_nodes[i][2]) asn_nodes_mutex.release() for AS in self.as_dest: if AS not in ASes: return False return True
def verify_signature(self, block): """ Verifies the origin of the miner of the block :param block: <Block> :return: <bool> True if signature is verified, False if not. """ ASN_pkey = None asn_nodes_mutex.acquire() for asn in ASN_nodes: # find miner's public key if block.miner == asn[2]: ASN_pkey = asn[-1] break asn_nodes_mutex.release() if ASN_pkey is not None: block_hash = block.calculate_hash() return ASN_pkey.verify(block_hash.encode(), block.signature) else: return False
def check_network(self): """ Checks if all the ASNs in the source and dest are in the blockchain network. :return: <bool> True if they are in the network, False otherwise. """ ASes = ['0'] asn_nodes_mutex.acquire() for i in range(len(ASN_nodes)): ASes.append(ASN_nodes[i][2]) asn_nodes_mutex.release() for AS in self.as_dest_list: if AS not in ASes: return False for AS in self.as_source_list: if AS not in ASes: return False return True