def handler(event, context): # initialize logger module logger = Logger(event, context) # Load config handler config = Config(context) ## ==== Sample code to fetch environment specific configurations ==== # myconfig = config.get_config('default') === "default" is the section over here # logger.info ('One of the environment configuration: config_key => ' + myconfig['config_key']) ## ==== Log message samples ==== # logger.error('Runtime errors or unexpected conditions.') # logger.warn('Runtime situations that are undesirable, but not wrong') # logger.info('Interesting runtime events eg. connection established)') # logger.verbose('Generally speaking, most log lines should be verbose.') # logger.debug('Detailed information on the flow through the system.') myconfig = config.get_config('default') logger.info('Sample response for function1.') return { "message": "Your function executed successfully!", "event": event, "myconfig": myconfig['config_key'] }
def _send_superdense(packet): """ Encodes and sends a qubit to send a superdense message. Args: packet (Packet): The packet in which to transmit. """ sender = packet.sender receiver = packet.receiver host_sender = network.get_host(sender) if not network.shares_epr(sender, receiver): Logger.get_instance().log('No shared EPRs - Generating one between ' + sender + " and " + receiver) q_id, _ = host_sender.send_epr(receiver, await_ack=True, block=True) assert q_id is not None q_superdense = host_sender.get_epr(receiver, q_id=q_id, wait=WAIT_TIME) else: q_superdense = host_sender.get_epr(receiver, wait=5) if q_superdense is None: Logger.get_instance().log('Failed to get EPR with ' + sender + " and " + receiver) raise Exception("couldn't encode superdense") _encode_superdense(packet.payload, q_superdense) packet.payload = q_superdense packet.protocol = REC_SUPERDENSE packet.payload_type = QUANTUM network.send(packet)
def routing_algorithm(di_graph, source, target): # Generate entanglement network entanglement_network = nx.DiGraph() nodes = di_graph.nodes() for node in nodes: host = network.get_host(node) host_connections = host.get_connections() for connection in host_connections: if connection['type'] == 'quantum': num_epr_pairs = len( host.get_epr_pairs(connection['connection'])) if num_epr_pairs == 0: entanglement_network.add_edge(host.host_id, connection['connection'], weight=1000) else: entanglement_network.add_edge(host.host_id, connection['connection'], weight=1. / num_epr_pairs) try: route = nx.shortest_path(entanglement_network, source, target, weight='weight') print('-------' + str(route) + '-------') return route except Exception as e: Logger.get_instance().error(e)
def _entanglement_swap(self, sender, receiver, route, q_id, o_seq_num, blocked): """ Performs a chain of entanglement swaps with the hosts between sender and receiver to create a shared EPR pair between sender and receiver. Args: sender (Host): Sender of the EPR pair receiver (Host): Receiver of the EPR pair route (list): Route between the sender and receiver q_id (string): Qubit ID of the sent EPR pair blocked (bool): If the pair being distributed is blocked or not """ host_sender = self.get_host(sender) # TODO: Multiprocess this # Create EPR pairs on the route, where all EPR qubits have the id q_id for i in range(len(route) - 1): if not self.shares_epr(route[i], route[i + 1]): self.get_host(route[i]).send_epr(route[i + 1], q_id, await_ack=True) else: old_id = self.get_host(route[i]).change_epr_qubit_id(route[i + 1], q_id) self.get_host(route[i + 1]).change_epr_qubit_id(route[i], q_id, old_id) for i in range(len(route) - 2): host = self.get_host(route[i + 1]) q = host.get_epr(route[0], q_id, wait=10) if q is None: print("Host is %s" % host.host_id) print("Search host is %s" % route[0]) print("Search id is %s" % q_id) print("EPR storage is") print(host._EPR_store) Logger.get_instance().error('Entanglement swap failed') return data = {'q': q, 'q_id': q_id, 'node': sender, 'o_seq_num': o_seq_num, 'type': protocols.EPR} if route[i + 2] == route[-1]: data = {'q': q, 'q_id': q_id, 'node': sender, 'ack': True, 'o_seq_num': o_seq_num, 'type': protocols.EPR} host.send_teleport(route[i + 2], None, await_ack=True, payload=data, generate_epr_if_none=False) # Change in the storage that the EPR qubit is shared with the receiver q2 = host_sender.get_epr(route[1], q_id=q_id) host_sender.add_epr(receiver, q2, q_id, blocked) Logger.get_instance().log('Entanglement swap was successful for pair with id ' + q_id + ' between ' + sender + ' and ' + receiver)
def add_host(self, host): """ Adds the *host* to ARP table and updates the network graph. Args: host (Host): The host to be added to the network. """ Logger.get_instance().debug('host added: ' + host.host_id) self.ARP[host.host_id] = host self._update_network_graph(host)
def _rec_qubit(packet): """ Receive a packet containing qubit information (qubit is transmitted externally) Args: packet (Packet): The packet in which to receive. """ Logger.get_instance().log(packet.receiver + ' received qubit ' + packet.payload.id + ' from ' + packet.sender) if packet.await_ack: _send_ack(packet.sender, packet.receiver, packet.seq_num)
def _send_ack(sender, receiver, seq_number): """ Send an acknowledge message from the sender to the receiver. Args: sender (string): The sender ID receiver (string): The receiver ID seq_number (int): The sequence number which to ACK """ Logger.get_instance().log('sending ACK:' + str(seq_number + 1) + ' from ' + receiver + " to " + sender) host_receiver = network.get_host(receiver) host_receiver.send_ack(sender, seq_number)
def _remove_network_node(self, host): """ Removes the host from the ARP table. Args: host (Host): The host to be removed from the network. """ try: self.classical_network.remove_node(host.host_id) except nx.NetworkXError: Logger.get_instance().error('attempted to remove a non-exiting node from network')
def stop(self, stop_hosts=False): """ Stops the network. """ Logger.get_instance().log("Network stopped") if stop_hosts: for host in self.ARP: self.ARP[host].stop(release_qubits=True) self._stop_thread = True if self._backend is not None: self._backend.stop()
def _relay_message(packet): """ Reduce TTL of network packet and if TTL > 0, sends the message to be relayed to the next node in the network and modifies the header. Args: packet (RoutingPacket): Packet to be relayed """ packet.ttl -= 1 if packet.ttl != 0: network.send(packet) else: Logger.get_instance().log('TTL Expired on packet')
def transfer_qubits(r, store=False, original_sender=None): for q in qubits: Logger.get_instance().log('transfer qubits - sending qubit ' + q.id) x_err_var = random.random() z_err_var = random.random() if x_err_var > (1 - self.x_error_rate): q.X() if z_err_var > (1 - self.z_error_rate): q.Z() q.send_to(self.ARP[r].host_id) Logger.get_instance().log('transfer qubits - received ' + q.id) # Unblock qubits in case they were blocked q.set_blocked_state(False) if store and original_sender is not None: self.ARP[r].add_data_qubit(original_sender, q)
def process(packet): """ Decodes the packet and processes the packet according to the protocol in the packet header. Args: packet (Packet): Packet to be processed. Returns: Returns what protocol function returns. """ protocol = packet.protocol if protocol == SEND_TELEPORT: return _send_teleport(packet) elif protocol == REC_TELEPORT: return _rec_teleport(packet) elif protocol == SEND_CLASSICAL: return _send_classical(packet) elif protocol == REC_CLASSICAL: return _rec_classical(packet) elif protocol == REC_EPR: return _rec_epr(packet) elif protocol == SEND_EPR: return _send_epr(packet) elif protocol == SEND_SUPERDENSE: return _send_superdense(packet) elif protocol == REC_SUPERDENSE: return _rec_superdense(packet) elif protocol == SEND_QUBIT: return _send_qubit(packet) elif protocol == REC_QUBIT: return _rec_qubit(packet) elif protocol == RELAY: return _relay_message(packet) elif protocol == SEND_KEY: return _send_key(packet) elif protocol == REC_KEY: return _rec_key(packet) else: Logger.get_instance().error('protocol not defined')
def qtcp_sender(host, q_size, receiver_id, checksum_size_per_qubit): """ Establishes a handshake and sends the data qubits to the receiver if handshake is successful. :param host: Sender of qubits :param q_size: Number of qubits to be sent :param receiver_id: ID of the receiver :param checksum_size_per_qubit: Checksum qubit per data qubit size :return: """ global thread_1_return tcp_connection = handshake_sender(host, receiver_id) if not tcp_connection: Logger.get_instance().log('Connection terminated.') thread_1_return = False return else: packet_transmission = qubit_send_w_retransmission( host, q_size, receiver_id, checksum_size_per_qubit) if packet_transmission: Logger.get_instance().log('Connection was successful.') thread_1_return = True return else: Logger.get_instance().log('Connection was not successful.') thread_1_return = False return
def _route_quantum_info(self, sender, receiver, qubits): """ Routes qubits from sender to receiver. Args: sender (Host): Sender of qubits receiver (Host): Receiver qubits qubits (List of Qubits): The qubits to be sent """ def transfer_qubits(r, store=False, original_sender=None): for q in qubits: Logger.get_instance().log('transfer qubits - sending qubit ' + q.id) x_err_var = random.random() z_err_var = random.random() if x_err_var > (1 - self.x_error_rate): q.X() if z_err_var > (1 - self.z_error_rate): q.Z() q.send_to(self.ARP[r].host_id) Logger.get_instance().log('transfer qubits - received ' + q.id) # Unblock qubits in case they were blocked q.set_blocked_state(False) if store and original_sender is not None: self.ARP[r].add_data_qubit(original_sender, q) route = self.get_quantum_route(sender, receiver) i = 0 while i < len(route) - 1: Logger.get_instance().log('sending qubits from ' + route[i] + ' to ' + route[i + 1]) if len(route[i:]) != 2: transfer_qubits(route[i + 1]) else: transfer_qubits(route[i + 1], store=True, original_sender=route[0]) i += 1
def _rec_classical(packet): """ Receives a classical message packet , parses it into sequence number and message and sends an ACK message to receiver. Args: packet (Packet): The packet in which to receive. Returns: dict : A dictionary consisting of 'message' and 'sequence number' """ if packet.payload == ACK: Logger.get_instance().log(packet.receiver + " received ACK from " + packet.sender + " with sequence number " + str(packet.seq_num)) if packet.await_ack: _send_ack(packet.sender, packet.receiver, packet.seq_num) return { 'sender': packet.sender, 'message': packet.payload, 'sequence_number': packet.seq_num }
def handler(event, context): try: # initialize logger module logger = Logger(event, context) # Load config handler. config = Config(event) ## ==== Sample code to fetch environment specific configurations ==== # myconfig = config.get_config('default') # logger.info ('One of the environment configuration: config_key => ' + myconfig['config_key']) ## ==== Log message samples ==== # logger.error('Runtime errors or unexpected conditions.') # logger.warn('Runtime situations that are undesirable, but not wrong') # logger.info('Interesting runtime events eg. connection established)') # logger.verbose('Generally speaking, most log lines should be verbose.') # logger.debug('Detailed information on the flow through the system.') # This is the happy path data = { 'key': 'value' } response = "" if 'method' in event: if event['method'] == "POST": # Handle Post response here response = CustomResponse(data, event['body']).get_json() else: # Handle Get/other response here. response = CustomResponse(data, event['query']).get_json() return response except Exception as e: # Exception Handling exception_type = e.__class__.__name__ exception_message = e.message # Create a JSON string here api_exception_json = CustomErrors.throwInternalServerError( exception_message) raise LambdaException(api_exception_json)
def __init__(self, host_id, backend=None): """ Return the most important thing about a person. Args: host_id: The ID of the host backend: The backend to use for this host """ self._host_id = host_id self._packet_queue = Queue() self._stop_thread = False self._queue_processor_thread = None self._data_qubit_store = QuantumStorage() self._EPR_store = QuantumStorage() self._classical_messages = ClassicalStorage() self._classical_connections = [] self._quantum_connections = [] if backend is None: self._backend = CQCBackend() else: self._backend = backend # add this host to the backend self._backend.add_host(self) self._max_ack_wait = None # Frequency of queue processing self._delay = 0.1 self.logger = Logger.get_instance() # Packet sequence numbers per connection self._max_window = 10 # [Queue, sender, seq_num, timeout, start_time] self._ack_receiver_queue = [] # sender: host -> int self._seq_number_sender = {} # sender_ack: host->[received_list, low_number] self._seq_number_sender_ack = {} # receiver: host->[received_list, low_number] self._seq_number_receiver = {} self.qkd_keys = {}
def __init__(self): self.pg_dump_path = "/opt/PostgreSQL/9.6/bin/pg_dump" # initializing DB Configuration Handler self.db_config_handler = DBConfiguration() # fetching DB configuration self.db_configuration_dict = self.db_config_handler # initialize logging parameters self.log_params = { "error": { "file_name": "error.log", "log_dir": settings.LOG_DIR, "stream_handler": None, "file_handler": True } } # initializing scp handler self.scp_handler = SCPHandler( **settings.REMOTE_SERVER_CREDENTIAL["remote_vps"]) self.error_logger = Logger(**self.log_params["error"])
def main(): config = configparser.ConfigParser() config.read('config.ini') config = config['default'] make_logging_directory_if_not_exists(directory=config.get('logging_path')) logger = Logger( fpath=os.path.join(config.get('logging_path'), 'log'), rotation_interval=config.get('log_rotation_interval'), rotation_frequency=config.getint('log_rotation_frequency'), ) buffer = TimedStringBuffer( logger = logger, threshold = config.getfloat('sentence_max_delta_seconds'), render_backspaces = config.getboolean('render_backspaces') ) keyboard.on_press(callback=buffer.add) try: keyboard.wait() except KeyboardInterrupt: sys.exit(0)
def handshake_receiver(host, sender_id): """ Establishes a classical TCP-like handshake with the sender . If successful starts to receive the qubits , otherwise terminated the connection. :param host: Receiver host :param sender_id: ID of the sender :return: If successful returns True, otherwise False """ latest_seq_num = host.get_sequence_number(sender_id) # Receive the EPR half of Alice and the SYN message qb_2 = host.get_data_qubit(sender_id, wait=WAIT_TIME) if qb_2 is None: Logger.get_instance().log('qb_2 is None') return False qb_2 = qb_2['q'] message_recv = host.get_message_w_seq_num(sender_id, (latest_seq_num + 1), wait=WAIT_TIME) if not message_recv: Logger.get_instance().log('No message has arrived') return False message_recv = message_recv[0]['message'] if message_recv == '10': Logger.get_instance().log("SYN is received by Bob") else: return False # Create an EPR pair. qb_3 = Qubit(host) qb_4 = Qubit(host) qb_3.H() qb_3.cnot(qb_4) # Send half of the EPR pair created (qubit 3) and send back the qubit 2 that Alice has sent first. _, ack_received = host.send_qubit(sender_id, qb_2, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False _, ack_received = host.send_qubit(sender_id, qb_3, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False # Send SYN-ACK message. host.send_classical(sender_id, SYN_ACK, True) latest_seq_num = host.get_sequence_number(sender_id) # Receive the ACK message. message = host.get_message_w_seq_num(sender_id, latest_seq_num, wait=WAIT_TIME) if message is None: Logger.get_instance().log('ACK was not received by Bob') return False if message.content == '01': Logger.get_instance().log('ACK was received by Bob') # Receive the qubit 3. qa_3 = host.get_data_qubit(sender_id, wait=WAIT_TIME) if qa_3 is None: return False # Make a Bell State measurement in qubit 3 and qubit 4. qa_3.cnot(qb_4) qa_3.H() qa_3_check = qa_3.measure() qb_4_check = qb_4.measure() # If measurement results are as expected , establish the TCP connection. # Else report that there is something wrong. if qa_3_check == 0 and qb_4_check == 0: Logger.get_instance().log("TCP connection established.") return True else: Logger.get_instance().log("Something is wrong.") return False
def main(): global thread_1_return global thread_2_return network = Network.get_instance() nodes = ["Alice", "Bob", "Eve", "Dean"] network.start(nodes) network.delay = 0.5 host_alice = Host('Alice') host_alice.add_connection('bob') host_alice.max_ack_wait = 30 host_alice.delay = 0.2 host_alice.start() host_bob = Host('Bob') host_bob.max_ack_wait = 30 host_bob.delay = 0.2 host_bob.add_connection('Alice') host_bob.add_connection('Eve') host_bob.start() host_eve = Host('Eve') host_eve.max_ack_wait = 30 host_eve.delay = 0.2 host_eve.add_connection('Bob') host_eve.add_connection('Dean') host_eve.start() host_dean = Host('Dean') host_dean.max_ack_wait = 30 host_dean.delay = 0.2 host_dean.add_connection('Eve') host_dean.start() network.add_host(host_alice) network.add_host(host_bob) network.add_host(host_eve) network.add_host(host_dean) network.x_error_rate = 0 network.packet_drop_rate = 0 q_size = 6 checksum_per_qubit = 2 host_alice.run_protocol(qtcp_sender, (q_size, host_dean.host_id, checksum_per_qubit)) host_dean.run_protocol(qtcp_receiver, (q_size, host_alice.host_id, checksum_per_qubit)) while thread_1_return is None or thread_2_return is None: if thread_1_return is False or thread_2_return is False: Logger.get_instance().log( 'TCP Connection not successful : EXITING') sys.exit(1) pass thread_1_return = None thread_2_return = None Logger.get_instance().log('PACKET 1') host_alice.run_protocol(qtcp_sender, (q_size, host_dean.host_id, checksum_per_qubit)) host_dean.run_protocol(qtcp_receiver, (q_size, host_alice.host_id, checksum_per_qubit)) while thread_1_return is None or thread_2_return is None: if thread_1_return is False or thread_2_return is False: Logger.get_instance().log( 'TCP Connection not successful : EXITING') sys.exit(1) pass Logger.get_instance().log('PACKET 2') host_alice.run_protocol(qtcp_sender, (q_size, host_dean.host_id, checksum_per_qubit)) host_dean.run_protocol(qtcp_receiver, (q_size, host_alice.host_id, checksum_per_qubit)) while thread_1_return is None or thread_2_return is None: if thread_1_return is False or thread_2_return is False: Logger.get_instance().log( 'TCP Connection not successful : EXITING') sys.exit(1) pass start_time = time.time() while time.time() - start_time < 150: pass network.stop(stop_hosts=True) exit()
def qubit_recv_w_retransmission(host, q_size, sender_id, checksum_size_per_qubit): """ Receives the data qubits with the possibility of retransmission. Then decodes the qubits , with checksum qubits and outputs the classical bits that has been sent. :param host: Receiver host :param q_size: Qubit size to be received :param sender_id: ID of the sender :param checksum_size_per_qubit: Checksum qubit per data qubit size :return: """ qubits = [] number_of_retranmissions = 0 checksum_size = int(q_size / checksum_size_per_qubit) for i in range(q_size + checksum_size): while len(qubits) < (q_size + checksum_size): need_retransmission = True while need_retransmission and number_of_retranmissions < MAX_NUM_OF_TRANSMISSIONS: q = host.get_data_qubit(sender_id, wait=WAIT_TIME) if q is not None: need_retransmission = False qubits.append(q) Logger.get_instance().log('Bob: received qubit') else: Logger.get_instance().log("Bob: didn't receive the qubit") host.send_classical('Alice', 'NACK', False) # Simulate qubit loss q.release() number_of_retranmissions += 1 if number_of_retranmissions == MAX_NUM_OF_TRANSMISSIONS: Logger.get_instance().log("Bob: too many attempts made") return False checksum_qubits = [] checksum_cnt = 0 checksum_size = int(q_size / checksum_size_per_qubit) for i in range(len(qubits)): if checksum_cnt < checksum_size: checksum_qubits.append(qubits[q_size + i]['q']) checksum_cnt = checksum_cnt + 1 checksum_cnt = 1 for i in range(len(qubits) - checksum_size): qubits[i]['q'].cnot(checksum_qubits[checksum_cnt - 1]) if i == (checksum_cnt * checksum_size_per_qubit - 1): checksum_cnt = checksum_cnt + 1 errors = 0 for i in range(len(checksum_qubits)): if checksum_qubits[i].measure() != 0: errors += 1 print('---------') if errors == 0: Logger.get_instance().log('No error exist in UDP packet') else: Logger.get_instance().log('There were errors in the UDP transmission') print('---------') rec_bits = [] for i in range(len(qubits) - checksum_size): rec_bits.append(qubits[i]['q'].measure()) if errors == 0: print('---------') Logger.get_instance().log('Receiver received the classical bits: ' + str(rec_bits)) print('---------') return True
def handshake_sender(host, receiver_id): """ Establishes a classical TCP-like handshake with the receiver . If successful starts the transmission of qubits , otherwise terminated the connection. :param host: Sender of qubits :param receiver_id: ID of the receiver :return: If successful returns True, otherwise False """ # Create an EPR pair. qa_1 = Qubit(host) qa_2 = Qubit(host) qa_1.H() qa_1.cnot(qa_2) # Send a half of EPR pair and the SYN message to Bob. _, ack_received = host.send_qubit(receiver_id, qa_2, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False ack_received = host.send_classical(receiver_id, SYN, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False syn_seq_num = host.get_sequence_number(receiver_id) # Receive the qubits Bob has sent (qubit 2 and qubit 3) for SYN-ACK. qb_2 = host.get_data_qubit(receiver_id, wait=WAIT_TIME) if qb_2 is None: return False qb_3 = host.get_data_qubit(receiver_id, wait=WAIT_TIME) if qb_3 is None: return False # Receive the classical message Bob has sent for SYN-ACK. message_recv = host.get_message_w_seq_num(receiver_id, syn_seq_num + 2, wait=WAIT_TIME) if message_recv is None: return False if message_recv.content == '11': Logger.get_instance().log("SYN-ACK is received by Alice") else: Logger.get_instance().log('Connection terminated - 1 ') return False # Make a Bell State measurement on qubit 1 and qubit 2. qa_1.cnot(qb_2) qa_1.H() qa_1_check = qa_1.measure() qb_2_check = qb_2.measure() # If measurement results are as expected, send Bob a ACK message and the qubit 3 that he has sent previously. # Else report that there is something wrong. if qa_1_check == 0 and qb_2_check == 0: latest_seq_num = host.get_sequence_number(receiver_id) ack_received = host.send_classical(receiver_id, ACK, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False _, ack_received = host.send_qubit(receiver_id, qb_3, await_ack=True) if ack_received is False: Logger.get_instance().log('ACK is not received') return False message = host.get_message_w_seq_num(receiver_id, latest_seq_num + 2, wait=WAIT_TIME) return message.content == 'ACK' else: Logger.get_instance().log("Something is wrong.") return False
def qubit_send_w_retransmission(host, q_size, receiver_id, checksum_size_per_qubit): """ Sends the data qubits along with checksum qubits , with the possibility of retransmission. :param host: Sender of qubits :param q_size: Number of qubits to be sent :param receiver_id: ID of the receiver :param checksum_size_per_qubit: Checksum qubit per data qubit size :return: """ bit_arr = np.random.randint(2, size=q_size) Logger.get_instance().log('Bit array to be sent: ' + str(bit_arr)) qubits = [] for i in range(q_size): q_tmp = Qubit(host) if bit_arr[i] == 1: q_tmp.X() qubits.append(q_tmp) check_qubits = host.add_checksum(qubits, checksum_size_per_qubit) checksum_size = int(q_size / checksum_size_per_qubit) qubits.append(check_qubits) checksum_cnt = 0 for i in range(q_size + checksum_size): if i < q_size: q = qubits[i] else: q = qubits[q_size][checksum_cnt] checksum_cnt = checksum_cnt + 1 q_success = False got_ack = False number_of_retransmissions = 0 while not got_ack and number_of_retransmissions < MAX_NUM_OF_TRANSMISSIONS: Logger.get_instance().log('Alice prepares qubit') err_1 = Qubit(host) # encode logical qubit q.cnot(err_1) host.send_qubit(receiver_id, q, await_ack=True) messages = host.get_classical(receiver_id, wait=WAIT_TIME) if messages[0].content == 'ACK': err_1.release() got_ack = True q_success = True if not q_success: Logger.get_instance().log( 'Alice: Bob did not receive the qubit') # re-introduce a qubit to the system and correct the error q = Qubit(host) err_1.cnot(q) number_of_retransmissions += 1 if number_of_retransmissions == 10: Logger.get_instance().log("Alice: too many attempts made") return False return True
def _send_teleport(packet): """ Does the measurements for teleportation of a qubit and sends the measurement results to another host. Args: packet (Packet): The packet in which to transmit. """ if 'node' in packet.payload: node = packet.payload['node'] else: node = packet.sender if 'type' in packet.payload: q_type = packet.payload['type'] else: q_type = DATA q = packet.payload['q'] q_id = q.id host_sender = network.get_host(packet.sender) if GENERATE_EPR_IF_NONE in packet.payload and packet.payload[ GENERATE_EPR_IF_NONE]: if not network.shares_epr(packet.sender, packet.receiver): Logger.get_instance().log( 'No shared EPRs - Generating one between ' + packet.sender + " and " + packet.receiver) host_sender.send_epr(packet.receiver, q_id=q_id, await_ack=True, block=True) if 'q_id' in packet.payload: epr_teleport = host_sender.get_epr(packet.receiver, packet.payload['q_id'], wait=WAIT_TIME) else: epr_teleport = host_sender.get_epr(packet.receiver, q_id, wait=WAIT_TIME) assert epr_teleport is not None q.cnot(epr_teleport) q.H() m1 = q.measure() m2 = epr_teleport.measure() data = {'measurements': [m1, m2], 'type': q_type, 'node': node} if q_type == EPR: data['q_id'] = packet.payload['q_id'] else: data['q_id'] = epr_teleport.id if 'o_seq_num' in packet.payload: data['o_seq_num'] = packet.payload['o_seq_num'] if 'ack' in packet.payload: data['ack'] = packet.payload['ack'] packet.payload = data packet.protocol = REC_TELEPORT network.send(packet)
def _process_queue(self): """ Runs a thread for processing the packets in the packet queue. """ while True: if self._stop_thread: break if not self._packet_queue.empty(): # Artificially delay the network if self.delay > 0: time.sleep(self.delay) packet = self._packet_queue.get() # Simulate packet loss packet_drop_var = random.random() if packet_drop_var > (1 - self.packet_drop_rate): Logger.get_instance().log("PACKET DROPPED") continue sender, receiver = packet.sender, packet.receiver if packet.payload_type == protocols.QUANTUM: self._route_quantum_info(sender, receiver, [packet.payload]) try: if packet.protocol == protocols.RELAY and not self.use_hop_by_hop: full_route = packet.route route = full_route[full_route.index(sender):] else: if packet.protocol == protocols.REC_EPR: route = self.get_quantum_route(sender, receiver) else: route = self.get_classical_route(sender, receiver) if len(route) < 2: raise Exception('No route exists') elif len(route) == 2: if packet.protocol != protocols.RELAY: if packet.protocol == protocols.REC_EPR: host_sender = self.get_host(sender) q = host_sender \ .backend \ .create_EPR(host_sender.host_id, receiver, q_id=packet.payload['q_id'], block=packet.payload['blocked']) host_sender.add_epr(receiver, q) self.ARP[receiver].rec_packet(packet) else: self.ARP[receiver].rec_packet(packet.payload) else: if packet.protocol == protocols.REC_EPR: q_id = packet.payload['q_id'] blocked = packet.payload['blocked'] q_route = self.get_quantum_route(sender, receiver) DaemonThread(self._entanglement_swap, args=(sender, receiver, q_route, q_id, packet.seq_num, blocked)) else: network_packet = self._encode(route, packet) self.ARP[route[1]].rec_packet(network_packet) except nx.NodeNotFound: Logger.get_instance().error("route couldn't be calculated, node doesn't exist") except ValueError: Logger.get_instance().error("route couldn't be calculated, value error") except Exception as e: Logger.get_instance().error('Error in network: ' + str(e))