예제 #1
0
def test_matrix_discovery_room_offline_server(
    local_matrix_servers,
    retries_before_backoff,
    retry_interval,
    private_rooms,
):

    transport = MatrixTransport({
        'discovery_room':
        'discovery',
        'retries_before_backoff':
        retries_before_backoff,
        'retry_interval':
        retry_interval,
        'server':
        local_matrix_servers[0],
        'server_name':
        local_matrix_servers[0].netloc,
        'available_servers': [local_matrix_servers[0], 'https://localhost:1'],
        'private_rooms':
        private_rooms,
    })
    transport.start(MockRaidenService(None), MessageHandler(set()), '')
    gevent.sleep(.2)
    transport.stop()
    transport.get()
예제 #2
0
def run_test_regression_transport_global_queues_are_initialized_on_restart_for_services(
        raiden_network, number_of_nodes, token_addresses, network_wait,
        user_deposit_address):
    app0, app1 = raiden_network

    app0.config["services"]["monitoring_enabled"] = True

    # Send a transfer to make sure the state has a balance proof
    # to publish to the global matrix rooms
    token_address = token_addresses[0]

    amount = 10
    transfer(
        initiator_app=app1,
        target_app=app0,
        token_address=token_address,
        amount=amount,
        identifier=1,
        timeout=network_wait * number_of_nodes,
    )

    app0.stop()

    transport = MatrixTransport(app0.config["transport"]["matrix"])
    transport.send_async = Mock()
    transport._send_raw = Mock()

    old_start_transport = transport.start

    # Check that the queue is populated before the transport sends it and empties the queue
    def start_transport(*args, **kwargs):
        # Before restart the transport's global message queue should be initialized
        # There should be 2 messages in the global queue.
        # 1 for the PFS and the other for MS
        assert len(transport._global_send_queue) == 2
        # No other messages were sent at this point
        transport.send_async.assert_not_called()
        transport._send_raw.assert_not_called()
        old_start_transport(*args, **kwargs)

    transport.start = start_transport

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()
    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_one_to_n_address=app0.raiden.default_one_to_n_address,
        default_secret_registry=app0.raiden.default_secret_registry,
        default_service_registry=app0.raiden.default_service_registry,
        transport=transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        discovery=app0.raiden.discovery,
        user_deposit=app0.raiden.chain.user_deposit(user_deposit_address),
    )
    app0_restart.start()
def test_join_invalid_discovery(
    skip_if_not_matrix,
    local_matrix_server,
    private_rooms,
    retry_interval,
    retries_before_backoff,
):
    """_join_discovery_room tries to join on all servers on available_servers config

    If any of the servers isn't reachable by synapse, it'll return a 500 response, which needs
    to be handled, and if no discovery room is found on any of the available_servers, one in
    our current server should be created
    """
    transport = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_server,
        'server_name': 'matrix.local.raiden',
        'available_servers': ['http://invalid.server'],
        'private_rooms': private_rooms,
    })
    transport._client.api.retry_timeout = 0
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)

    transport.start(
        raiden_service,
        raiden_service.message_handler,
        None,
    )
    transport.log = MagicMock()

    transport._join_discovery_room()
    assert isinstance(transport._discovery_room, Room)

    transport.stop()
    transport.get()
예제 #4
0
def test_matrix_message_retry(
    local_matrix_servers,
    private_rooms,
    retry_interval,
    retries_before_backoff,
):
    """ Test the retry mechanism implemented into the matrix client.
    The test creates a transport and sends a message. Given that the
    receiver was online, the initial message is sent but the receiver
    doesn't respond in time and goes offline. The retrier should then
    wait for the `retry_interval` duration to pass and send the message
    again but this won't work because the receiver is offline. Once
    the receiver comes back again, the message should be sent again.
    """
    partner_address = make_address()

    transport = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_servers[0],
        'server_name': local_matrix_servers[0].netloc,
        'available_servers': [],
        'private_rooms': private_rooms,
    })
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)

    transport.start(
        raiden_service,
        raiden_service.message_handler,
        None,
    )
    transport.log = MagicMock()

    # Receiver is online
    transport._address_to_presence[partner_address] = UserPresence.ONLINE

    queueid = QueueIdentifier(
        recipient=partner_address,
        channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE,
    )
    chain_state = raiden_service.wal.state_manager.current_state

    retry_queue: _RetryQueue = transport._get_retrier(partner_address)
    assert bool(retry_queue), 'retry_queue not running'

    # Send the initial message
    message = Processed(0)
    message.sign(transport._raiden_service.private_key)
    chain_state.queueids_to_queues[queueid] = [message]
    retry_queue.enqueue_global(message)

    gevent.sleep(1)

    transport._send_raw.call_count = 1

    # Receiver goes offline
    transport._address_to_presence[partner_address] = UserPresence.OFFLINE

    gevent.sleep(retry_interval)

    transport.log.debug.assert_called_with(
        'Partner not reachable. Skipping.',
        partner=pex(partner_address),
        status=UserPresence.OFFLINE,
    )

    # Retrier did not call send_raw given that the receiver is still offline
    assert transport._send_raw.call_count == 1

    # Receiver comes back online
    transport._address_to_presence[partner_address] = UserPresence.ONLINE

    gevent.sleep(retry_interval)

    # Retrier now should have sent the message again
    assert transport._send_raw.call_count == 2

    transport.stop()
    transport.get()
예제 #5
0
def test_matrix_message_sync(
        local_matrix_servers,
        private_rooms,
        retry_interval,
        retries_before_backoff,
):
    transport0 = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_servers[0],
        'server_name': local_matrix_servers[0].netloc,
        'available_servers': [],
        'private_rooms': private_rooms,
    })
    transport1 = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_servers[0],
        'server_name': local_matrix_servers[0].netloc,
        'available_servers': [],
        'private_rooms': private_rooms,
    })

    latest_auth_data = None

    received_messages = set()

    message_handler = MessageHandler(received_messages)
    raiden_service0 = MockRaidenService(message_handler)
    raiden_service1 = MockRaidenService(message_handler)

    raiden_service1.handle_state_change = MagicMock()

    transport0.start(
        raiden_service0,
        message_handler,
        None,
    )
    transport1.start(
        raiden_service1,
        message_handler,
        None,
    )

    gevent.sleep(1)

    latest_auth_data = f'{transport1._user_id}/{transport1._client.api.token}'
    update_transport_auth_data = ActionUpdateTransportAuthData(latest_auth_data)
    raiden_service1.handle_state_change.assert_called_with(update_transport_auth_data)

    transport0.start_health_check(transport1._raiden_service.address)
    transport1.start_health_check(transport0._raiden_service.address)

    queue_identifier = QueueIdentifier(
        recipient=transport1._raiden_service.address,
        channel_identifier=1,
    )

    for i in range(5):
        message = Processed(i)
        message.sign(transport0._raiden_service.private_key)
        transport0.send_async(
            queue_identifier,
            message,
        )

    gevent.sleep(2)

    assert len(received_messages) == 10
    for i in range(5):
        assert any(getattr(m, 'message_identifier', -1) == i for m in received_messages)

    transport1.stop()

    assert latest_auth_data

    # Send more messages while the other end is offline
    for i in range(10, 15):
        message = Processed(i)
        message.sign(transport0._raiden_service.private_key)
        transport0.send_async(
            queue_identifier,
            message,
        )

    # Should fetch the 5 messages sent while transport1 was offline
    transport1.start(
        transport1._raiden_service,
        message_handler,
        latest_auth_data,
    )

    gevent.sleep(2)

    assert len(set(received_messages)) == 20
    for i in range(10, 15):
        assert any(getattr(m, 'message_identifier', -1) == i for m in received_messages)

    transport0.stop()
    transport1.stop()
    transport0.get()
    transport1.get()
예제 #6
0
def test_broadcast_messages_must_be_sent_before_protocol_messages_on_restarts(
    raiden_network, number_of_nodes, token_addresses, network_wait, user_deposit_address
):
    """ Raiden must broadcast the latest known balance proof on restarts.

    Regression test for: https://github.com/raiden-network/raiden/issues/3656.
    """
    app0, app1 = raiden_network
    app0.config["services"]["monitoring_enabled"] = True
    # Send a transfer to make sure the state has a balance proof to broadcast
    token_address = token_addresses[0]

    amount = PaymentAmount(10)
    payment_id = PaymentID(23)
    transfer(
        initiator_app=app1,
        target_app=app0,
        token_address=token_address,
        amount=amount,
        identifier=payment_id,
        timeout=network_wait * number_of_nodes,
    )

    app0.stop()

    transport = MatrixTransport(app0.config["transport"]["matrix"])
    transport.send_async = Mock()  # type: ignore
    transport._send_raw = Mock()  # type: ignore

    old_start_transport = transport.start

    # Asserts the balance proofs are broadcasted before protocol messages
    def start_transport(*args, **kwargs):
        # Before restart the transport's broadcast queue should be initialized
        # There should be 3 messages in the queue:
        # - A `MonitorRequest` to the MS
        # - A `PFSCapacityUpdate`
        # - A `PFSFeeUpdate`
        queue_copy = transport._broadcast_queue.copy()
        queued_messages = list()
        for _ in range(len(transport._broadcast_queue)):
            queued_messages.append(queue_copy.get())

        def num_matching_queued_messages(room: str, message_type: Type) -> int:
            return len(
                [
                    item
                    for item in queued_messages
                    if item[0] == room and type(item[1]) == message_type
                ]
            )

        assert num_matching_queued_messages(MONITORING_BROADCASTING_ROOM, RequestMonitoring) == 1
        assert num_matching_queued_messages(PATH_FINDING_BROADCASTING_ROOM, PFSFeeUpdate) == 1
        assert num_matching_queued_messages(PATH_FINDING_BROADCASTING_ROOM, PFSCapacityUpdate) == 1

        old_start_transport(*args, **kwargs)

    transport.start = start_transport  # type: ignore

    app0_restart = App(
        config=app0.config,
        rpc_client=app0.raiden.rpc_client,
        proxy_manager=app0.raiden.proxy_manager,
        query_start_block=BlockNumber(0),
        default_registry=app0.raiden.default_registry,
        default_one_to_n_address=app0.raiden.default_one_to_n_address,
        default_secret_registry=app0.raiden.default_secret_registry,
        default_service_registry=app0.raiden.default_service_registry,
        default_msc_address=app0.raiden.default_msc_address,
        transport=transport,
        raiden_event_handler=RaidenEventHandler(),
        message_handler=MessageHandler(),
        routing_mode=RoutingMode.PFS,  # not private mode, otherwise no PFS updates are queued
        user_deposit=app0.raiden.proxy_manager.user_deposit(user_deposit_address),
    )
    app0_restart.start()
예제 #7
0
def test_matrix_message_sync(
        skip_if_not_matrix,
        local_matrix_server,
        private_rooms,
        retry_interval,
        retries_before_backoff,
):
    transport0 = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_server,
        'server_name': 'matrix.local.raiden',
        'available_servers': [],
        'private_rooms': private_rooms,
    })
    transport1 = MatrixTransport({
        'discovery_room': 'discovery',
        'retries_before_backoff': retries_before_backoff,
        'retry_interval': retry_interval,
        'server': local_matrix_server,
        'server_name': 'matrix.local.raiden',
        'available_servers': [],
        'private_rooms': private_rooms,
    })

    latest_sync_token = None

    received_messages = set()

    def hook(sync_token):
        nonlocal latest_sync_token
        latest_sync_token = sync_token

    class MessageHandler:
        def on_message(self, _, message):
            nonlocal received_messages
            received_messages.add(message)

    transport0._client.set_post_sync_hook(hook)
    message_handler = MessageHandler()
    raiden_service0 = MockRaidenService(message_handler)
    raiden_service1 = MockRaidenService(message_handler)

    raiden_service1.handle_state_change = MagicMock()

    transport0.start(
        raiden_service0,
        message_handler,
        None,
    )
    transport1.start(
        raiden_service1,
        message_handler,
        None,
    )

    transport0.start_health_check(transport1._raiden_service.address)
    transport1.start_health_check(transport0._raiden_service.address)

    queue_identifier = QueueIdentifier(
        recipient=transport1._raiden_service.address,
        channel_identifier=1,
    )

    for i in range(5):
        message = Processed(i)
        message.sign(transport0._raiden_service.private_key)
        transport0.send_async(
            queue_identifier,
            message,
        )

    gevent.sleep(2)

    latest_sync_token = f'{transport1._user_id}/{latest_sync_token}'
    update_transport_sync_token = ActionUpdateTransportSyncToken(latest_sync_token)
    raiden_service1.handle_state_change.assert_called_with(update_transport_sync_token)

    assert len(received_messages) == 10
    for i in range(5):
        assert any(getattr(m, 'message_identifier', -1) == i for m in received_messages)

    transport1.stop()

    assert latest_sync_token

    # Send more messages while the other end is offline
    for i in range(10, 15):
        message = Processed(i)
        message.sign(transport0._raiden_service.private_key)
        transport0.send_async(
            queue_identifier,
            message,
        )

    # Should fetch the 5 messages sent while transport1 was offline
    transport1.start(
        transport1._raiden_service,
        message_handler,
        latest_sync_token,
    )

    gevent.sleep(2)

    assert len(set(received_messages)) == 20
    for i in range(10, 15):
        assert any(getattr(m, 'message_identifier', -1) == i for m in received_messages)

    transport0.stop()
    transport1.stop()