예제 #1
0
async def test_packet_decoder_error():
    datagram_send_channel, datagram_receive_channel = trio.open_memory_channel(
        1)
    packet_send_channel, packet_receive_channel = trio.open_memory_channel(1)

    async with background_service(
            PacketDecoder(datagram_receive_channel, packet_send_channel)):
        # send invalid packet
        await datagram_send_channel.send(
            IncomingDatagram(
                datagram=b"not a valid packet",
                sender_endpoint=EndpointFactory(),
            ))

        # send valid packet
        packet = AuthTagPacketFactory()
        sender_endpoint = EndpointFactory()
        await datagram_send_channel.send(
            IncomingDatagram(
                datagram=packet.to_wire_bytes(),
                sender_endpoint=sender_endpoint,
            ))

        # ignore the invalid one, only receive the valid one
        with trio.fail_after(0.5):
            incoming_packet = await packet_receive_channel.receive()

        assert incoming_packet.packet == packet
        assert incoming_packet.sender_endpoint.ip_address == sender_endpoint.ip_address
        assert incoming_packet.sender_endpoint.port == sender_endpoint.port
예제 #2
0
async def test_trio_service_manager_run_task_can_still_cancel_after_run_finishes(
):
    task_event = trio.Event()
    service_finished = trio.Event()

    @as_service
    async def RunTaskService(manager):
        async def task_fn():
            # this will never complete
            await task_event.wait()

        manager.run_task(task_fn)
        # the task is set to run in the background but then  the service exits.
        # We want to be sure that the task is allowed to continue till
        # completion unless explicitely cancelled.
        service_finished.set()

    async with background_service(RunTaskService()) as manager:
        with trio.fail_after(0.01):
            await service_finished.wait()

        # show that the service hangs waiting for the task to complete.
        with trio.move_on_after(0.01) as cancel_scope:
            await manager.wait_stopped()
        assert cancel_scope.cancelled_caught is True

        # trigger cancellation and see that the service actually stops
        manager.cancel()
        with trio.fail_after(0.01):
            await manager.wait_stopped()
예제 #3
0
async def message_dispatcher(enr_db, incoming_message_channels, outgoing_message_channels):
    message_dispatcher = MessageDispatcher(
        enr_db=enr_db,
        incoming_message_receive_channel=incoming_message_channels[1],
        outgoing_message_send_channel=outgoing_message_channels[0],
    )
    async with background_service(message_dispatcher):
        yield message_dispatcher
예제 #4
0
async def test_logs_handling(
    w3,
    deposit_contract,
    tester,
    num_blocks_confirmed,
    polling_period,
    endpoint_server,
    func_do_deposit,
    start_block_number,
):
    amount_0 = func_do_deposit()
    amount_1 = func_do_deposit()
    m = Eth1Monitor(
        w3=w3,
        deposit_contract_address=deposit_contract.address,
        deposit_contract_abi=deposit_contract.abi,
        num_blocks_confirmed=num_blocks_confirmed,
        polling_period=polling_period,
        start_block_number=start_block_number,
        event_bus=endpoint_server,
        base_db=AtomicDBFactory(),
    )
    async with background_service(m):
        # Test: logs emitted prior to starting `Eth1Monitor` can still be queried.
        await wait_all_tasks_blocked()
        assert m.total_deposit_count == 0
        assert m.highest_processed_block_number == 0

        tester.mine_blocks(num_blocks_confirmed - 1)
        # Test: only single deposit is processed.
        #      `num_blocks_confirmed`
        #       |-----------------|
        # [x] -> [x] -> [ ] -> [ ]
        await trio.sleep(polling_period)
        await wait_all_tasks_blocked()
        assert (m.total_deposit_count == 1
                and m._db.get_deposit_data(0).amount == amount_0)

        tester.mine_blocks(1)
        # Test: both deposits are processed.
        #             `num_blocks_confirmed`
        #              |-----------------|
        # [x] -> [x] -> [ ] -> [ ] -> [ ]
        await trio.sleep(polling_period)
        await wait_all_tasks_blocked()
        assert (m.total_deposit_count == 2
                and m._db.get_deposit_data(1).amount == amount_1)
        # Test: a new log can be queried after the transaction is included in a block
        #   and `num_blocks_confirmed` blocks are mined.
        #                                         `num_blocks_confirmed`
        #                                          |-----------------|
        # [x] -> [x] -> [ ] -> [ ] -> [ ] -> [x] -> [ ] -> [ ] -> [ ]
        amount_2 = func_do_deposit()
        tester.mine_blocks(num_blocks_confirmed)
        await trio.sleep(polling_period)
        await wait_all_tasks_blocked()
        assert (m.total_deposit_count == 3
                and m._db.get_deposit_data(2).amount == amount_2)
예제 #5
0
async def endpoint_tracker(private_key, initial_enr, enr_db, vote_channels):
    endpoint_tracker = EndpointTracker(
        local_private_key=private_key,
        local_node_id=initial_enr.node_id,
        enr_db=enr_db,
        identity_scheme_registry=default_identity_scheme_registry,
        vote_receive_channel=vote_channels[1],
    )
    async with background_service(endpoint_tracker):
        yield endpoint_tracker
async def ping_sender(local_enr, routing_table, message_dispatcher, enr_db,
                      incoming_message_channels, endpoint_vote_channels):
    ping_sender = PingSender(
        local_node_id=local_enr.node_id,
        routing_table=routing_table,
        message_dispatcher=message_dispatcher,
        enr_db=enr_db,
        endpoint_vote_send_channel=endpoint_vote_channels[0],
    )
    async with background_service(ping_sender):
        yield ping_sender
async def find_node_handler(local_enr, routing_table, message_dispatcher,
                            enr_db, incoming_message_channels,
                            outgoing_message_channels, endpoint_vote_channels):
    find_node_handler = FindNodeHandler(
        local_node_id=local_enr.node_id,
        routing_table=routing_table,
        message_dispatcher=message_dispatcher,
        enr_db=enr_db,
        outgoing_message_send_channel=outgoing_message_channels[0],
    )
    async with background_service(find_node_handler):
        yield ping_handler
예제 #8
0
async def test_trio_service_manager_run_task():
    task_event = trio.Event()

    @as_service
    async def RunTaskService(manager):
        async def task_fn():
            task_event.set()
        manager.run_task(task_fn)
        await manager.wait_cancelled()

    async with background_service(RunTaskService()):
        with trio.fail_after(0.1):
            await task_event.wait()
예제 #9
0
async def packer(enr_db, private_key, enr, incoming_packet_channels,
                 incoming_message_channels, outgoing_message_channels,
                 outgoing_packet_channels):
    packer = Packer(
        local_private_key=private_key,
        local_node_id=enr.node_id,
        enr_db=enr_db,
        message_type_registry=default_message_type_registry,
        incoming_packet_receive_channel=incoming_packet_channels[1],
        incoming_message_send_channel=incoming_message_channels[0],
        outgoing_message_receive_channel=outgoing_message_channels[1],
        outgoing_packet_send_channel=outgoing_packet_channels[0],
    )
    async with background_service(packer):
        yield packer
예제 #10
0
async def test_datagram_sender(socket_pair):
    sending_socket, receiving_socket = socket_pair
    receiver_address = receiving_socket.getsockname()
    sender_address = sending_socket.getsockname()

    send_channel, receive_channel = trio.open_memory_channel(1)
    async with background_service(
            DatagramSender(receive_channel, sending_socket)):
        outgoing_datagram = OutgoingDatagram(b"some packet", receiver_address)
        await send_channel.send(outgoing_datagram)

        with trio.fail_after(0.5):
            data, sender = await receiving_socket.recvfrom(1024)
        assert data == outgoing_datagram.datagram
        assert sender == sender_address
예제 #11
0
async def ping_handler_service(local_enr,
                               routing_table,
                               message_dispatcher,
                               enr_db,
                               incoming_message_channels,
                               outgoing_message_channels):
    ping_handler_service = PingHandlerService(
        local_node_id=local_enr.node_id,
        routing_table=routing_table,
        message_dispatcher=message_dispatcher,
        enr_db=enr_db,
        outgoing_message_send_channel=outgoing_message_channels[0],
    )
    async with background_service(ping_handler_service):
        yield ping_handler_service
예제 #12
0
async def test_trio_service_manager_stop():
    service = WaitCancelledService()

    async with background_service(service) as manager:
        assert manager.is_started is True
        assert manager.is_running is True
        assert manager.is_cancelled is False
        assert manager.is_stopped is False

        await manager.stop()

        assert manager.is_started is True
        assert manager.is_running is False
        assert manager.is_cancelled is True
        assert manager.is_stopped is True
예제 #13
0
async def test_trio_service_manager_run_task_waits_for_task_completion():
    task_event = trio.Event()

    @as_service
    async def RunTaskService(manager):
        async def task_fn():
            await trio.sleep(0.01)
            task_event.set()
        manager.run_task(task_fn)
        # the task is set to run in the background but then  the service exits.
        # We want to be sure that the task is allowed to continue till
        # completion unless explicitely cancelled.

    async with background_service(RunTaskService()):
        with trio.fail_after(0.1):
            await task_event.wait()
예제 #14
0
async def test_trio_service_manager_run_task_reraises_exceptions():
    task_event = trio.Event()

    @as_service
    async def RunTaskService(manager):
        async def task_fn():
            await task_event.wait()
            raise Exception("task exception in run_task")
        manager.run_task(task_fn)
        with trio.fail_after(1):
            await trio.sleep_forever()

    with pytest.raises(Exception, match="task exception in run_task"):
        async with background_service(RunTaskService()):
            task_event.set()
            with trio.fail_after(1):
                await trio.sleep_forever()
예제 #15
0
async def test_trio_service_manager_run_daemon_task_cancels_if_exits():
    task_event = trio.Event()

    @as_service
    async def RunTaskService(manager):
        async def daemon_task_fn():
            await task_event.wait()

        manager.run_daemon_task(daemon_task_fn, name='daemon_task_fn')
        with trio.fail_after(1):
            await trio.sleep_forever()

    with pytest.raises(DaemonTaskExit, match="Daemon task daemon_task_fn exited"):
        async with background_service(RunTaskService()):
            task_event.set()
            with trio.fail_after(1):
                await trio.sleep_forever()
예제 #16
0
async def test_datagram_receiver(socket_pair):
    sending_socket, receiving_socket = socket_pair
    receiver_address = receiving_socket.getsockname()
    sender_address = sending_socket.getsockname()

    send_channel, receive_channel = trio.open_memory_channel(1)
    async with background_service(
            DatagramReceiver(receiving_socket, send_channel)):
        data = b"some packet"

        await sending_socket.sendto(data, receiver_address)
        with trio.fail_after(0.5):
            received_datagram = await receive_channel.receive()

        assert received_datagram.datagram == data
        assert received_datagram.sender.ip_address == sender_address[0]
        assert received_datagram.sender.port == sender_address[1]
예제 #17
0
async def remote_packer(enr_db, remote_private_key, remote_enr,
                        remote_incoming_packet_channels,
                        remote_incoming_message_channels,
                        remote_outgoing_message_channels,
                        remote_outgoing_packet_channels, bridged_channels):
    remote_packer = Packer(
        local_private_key=remote_private_key,
        local_node_id=remote_enr.node_id,
        enr_db=enr_db,
        message_type_registry=default_message_type_registry,
        incoming_packet_receive_channel=remote_incoming_packet_channels[1],
        incoming_message_send_channel=remote_incoming_message_channels[0],
        outgoing_message_receive_channel=remote_outgoing_message_channels[1],
        outgoing_packet_send_channel=remote_outgoing_packet_channels[0],
    )
    async with background_service(remote_packer):
        yield packer
예제 #18
0
async def test_trio_service_background_service_context_manager():
    service = WaitCancelledService()

    async with background_service(service) as manager:
        # ensure the manager property is set.
        assert hasattr(service, 'manager')
        assert service.manager is manager

        assert manager.is_started is True
        assert manager.is_running is True
        assert manager.is_cancelled is False
        assert manager.is_stopped is False

    assert manager.is_started is True
    assert manager.is_running is False
    assert manager.is_cancelled is True
    assert manager.is_stopped is True
예제 #19
0
async def eth1_monitor(
    w3,
    deposit_contract,
    num_blocks_confirmed,
    polling_period,
    start_block_number,
    endpoint_server,
):
    m = Eth1Monitor(
        w3=w3,
        deposit_contract_address=deposit_contract.address,
        deposit_contract_abi=deposit_contract.abi,
        num_blocks_confirmed=num_blocks_confirmed,
        polling_period=polling_period,
        start_block_number=start_block_number,
        event_bus=endpoint_server,
    )
    async with background_service(m):
        yield m
예제 #20
0
async def test_packet_encoder():
    packet_send_channel, packet_receive_channel = trio.open_memory_channel(1)
    datagram_send_channel, datagram_receive_channel = trio.open_memory_channel(
        1)

    async with background_service(
            PacketEncoder(packet_receive_channel, datagram_send_channel)):
        receiver_endpoint = EndpointFactory()
        outgoing_packet = OutgoingPacket(
            packet=AuthTagPacketFactory(),
            receiver_endpoint=receiver_endpoint,
        )
        await packet_send_channel.send(outgoing_packet)

        with trio.fail_after(0.5):
            outgoing_datagram = await datagram_receive_channel.receive()

        assert outgoing_datagram.datagram == outgoing_packet.packet.to_wire_bytes(
        )
        assert outgoing_datagram.receiver_endpoint.ip_address == receiver_endpoint.ip_address
        assert outgoing_datagram.receiver_endpoint.port == receiver_endpoint.port