Beispiel #1
0
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']
    }
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
    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')
Beispiel #9
0
    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()
Beispiel #10
0
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')
Beispiel #11
0
        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)
Beispiel #12
0
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')
Beispiel #13
0
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
Beispiel #14
0
    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
Beispiel #15
0
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
    }
Beispiel #16
0
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)
Beispiel #17
0
    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 = {}
Beispiel #18
0
    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"])
Beispiel #19
0
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)
Beispiel #20
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
Beispiel #21
0
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()
Beispiel #22
0
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
Beispiel #23
0
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
Beispiel #24
0
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
Beispiel #25
0
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)
Beispiel #26
0
    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))