def test_processed():
    message_identifier = random.randint(0, constants.UINT64_MAX)
    processed_message = Processed(message_identifier=message_identifier,
                                  signature=constants.EMPTY_SIGNATURE)
    processed_message.sign(signer)
    assert processed_message.sender == ADDRESS
    assert processed_message.message_identifier == message_identifier
Esempio n. 2
0
def test_message_operators():
    message_identifier = 10
    message_identifier2 = 11

    a = Processed(message_identifier=message_identifier, signature=EMPTY_SIGNATURE)
    b = Processed(message_identifier=message_identifier, signature=EMPTY_SIGNATURE)
    c = Processed(message_identifier=message_identifier2, signature=EMPTY_SIGNATURE)

    # pylint: disable=unneeded-not
    assert a == b
    assert not a != b
    assert a != c
    assert not a == c
Esempio n. 3
0
def message_from_sendevent(send_event: SendMessageEvent) -> Message:
    if type(send_event) == SendLockedTransfer:
        assert isinstance(send_event, SendLockedTransfer), MYPY_ANNOTATION
        return LockedTransfer.from_event(send_event)
    elif type(send_event) == SendSecretReveal:
        assert isinstance(send_event, SendSecretReveal), MYPY_ANNOTATION
        return RevealSecret.from_event(send_event)
    elif type(send_event) == SendBalanceProof:
        assert isinstance(send_event, SendBalanceProof), MYPY_ANNOTATION
        return Unlock.from_event(send_event)
    elif type(send_event) == SendSecretRequest:
        assert isinstance(send_event, SendSecretRequest), MYPY_ANNOTATION
        return SecretRequest.from_event(send_event)
    elif type(send_event) == SendRefundTransfer:
        assert isinstance(send_event, SendRefundTransfer), MYPY_ANNOTATION
        return RefundTransfer.from_event(send_event)
    elif type(send_event) == SendLockExpired:
        assert isinstance(send_event, SendLockExpired), MYPY_ANNOTATION
        return LockExpired.from_event(send_event)
    elif type(send_event) == SendWithdrawRequest:
        return WithdrawRequest.from_event(send_event)
    elif type(send_event) == SendWithdrawConfirmation:
        return WithdrawConfirmation.from_event(send_event)
    elif type(send_event) == SendWithdrawExpired:
        return WithdrawExpired.from_event(send_event)
    elif type(send_event) == SendProcessed:
        assert isinstance(send_event, SendProcessed), MYPY_ANNOTATION
        return Processed.from_event(send_event)
    else:
        raise ValueError(f"Unknown event type {send_event}")
Esempio n. 4
0
def test_send_to_device(matrix_transports):
    transport0, transport1 = matrix_transports
    received_messages0 = set()
    received_messages1 = set()

    message_handler0 = MessageHandler(received_messages0)
    message_handler1 = MessageHandler(received_messages1)

    raiden_service0 = MockRaidenService(message_handler0)
    raiden_service1 = MockRaidenService(message_handler1)
    transport1._receive_to_device = MagicMock()

    transport0.start(raiden_service0, [], "")
    transport1.start(raiden_service1, [], "")

    transport0.start_health_check(raiden_service1.address)
    transport1.start_health_check(raiden_service0.address)

    message = Processed(message_identifier=1, signature=EMPTY_SIGNATURE)
    transport0._raiden_service.sign(message)
    transport0.send_to_device(raiden_service1.address, message)

    transport1._receive_to_device.assert_not_called()
    message = ToDevice(message_identifier=1, signature=EMPTY_SIGNATURE)
    transport0._raiden_service.sign(message)
    transport0.send_to_device(raiden_service1.address, message)
    with gevent.Timeout(2):
        wait_assert(transport1._receive_to_device.assert_called)
Esempio n. 5
0
def test_unhandled_message(pathfinding_service_mock, log):
    metrics_state = save_metrics_state(metrics.REGISTRY)

    unknown_message = Processed(MessageID(123), signature=EMPTY_SIGNATURE)
    unknown_message.sign(LocalSigner(PARTICIPANT1_PRIVKEY))

    pathfinding_service_mock.handle_message(unknown_message)

    # Although the message is unknown and will be ignored,
    # it is still logged under it's message type
    assert (metrics_state.get_delta(
        "messages_processing_duration_seconds_sum",
        labels={"message_type": "Processed"},
    ) > 0.0)
    assert (metrics_state.get_delta("messages_exceptions_total",
                                    labels={"message_type":
                                            "Processed"}) == 0.0)

    assert log.has("Ignoring message", unknown_message=unknown_message)
def test_message_ack_timing_keeper_edge_cases():
    matk = MessageAckTimingKeeper()

    # No measurements -> empty report
    assert matk.generate_report() == []

    # Unknown messages must be ignored
    processed = Processed(MessageID(999), make_signature())
    matk.finalize_message(processed)

    assert matk.generate_report() == []

    reveal_secret = RevealSecret(MessageID(1), make_signature(), make_secret())
    matk.add_message(reveal_secret)

    # In flight messages are not included in reports
    assert matk.generate_report() == []
Esempio n. 7
0
def test_message_ack_timing_keeper():
    matk = MessageAckTimingKeeper()

    matk.add_message(RevealSecret(MessageID(1), make_signature(), make_secret()))

    gevent.sleep(0.05)
    matk.finalize_message(Processed(MessageID(1), make_signature()))

    assert len(matk._durations) == 1
    assert 0.05 <= matk._durations[0] <= 0.06

    # Set duration to a fixed value
    matk._durations[0] = 0.05

    report = matk.generate_report()
    assert len(report) == 1
    assert report == [0.05]
Esempio n. 8
0
def test_web_rtc_message_sync(matrix_transports):

    transport0, transport1 = matrix_transports
    transport1_messages = set()

    raiden_service0 = MockRaidenService()
    raiden_service1 = MockRaidenService()

    def mock_handle_web_rtc_messages(message_data, partner_address):
        messages = validate_and_parse_message(message_data, partner_address)
        transport1_messages.update(messages)

    # set mock function to make sure messages are sent via web rtc
    transport1._web_rtc_manager._handle_message_callback = mock_handle_web_rtc_messages

    transport0.start(raiden_service0, [], None)
    transport1.start(raiden_service1, [], None)

    transport0.immediate_health_check_for(transport1._raiden_service.address)
    transport1.immediate_health_check_for(transport0._raiden_service.address)

    with Timeout(TIMEOUT_WEB_RTC_CONNECTION):
        # wait until web rtc connection is ready
        while not transport0._web_rtc_manager.has_ready_channel(raiden_service1.address):
            gevent.sleep(1)
        while not transport1._web_rtc_manager.has_ready_channel(raiden_service0.address):
            gevent.sleep(1)

    queue_identifier = QueueIdentifier(
        recipient=transport1._raiden_service.address,
        canonical_identifier=factories.UNIT_CANONICAL_ID,
    )

    raiden0_queues = views.get_all_messagequeues(views.state_from_raiden(raiden_service0))
    raiden0_queues[queue_identifier] = []

    for i in range(5):
        message = Processed(message_identifier=MessageID(i), signature=EMPTY_SIGNATURE)
        raiden0_queues[queue_identifier].append(message)
        transport0._raiden_service.sign(message)
        transport0.send_async([MessagesQueue(queue_identifier, [message])])

    with Timeout(TIMEOUT_MESSAGE_RECEIVE):
        while not len(transport1_messages) == 5:
            gevent.sleep(0.1)
Esempio n. 9
0
def test_matrix_broadcast(
    local_matrix_servers,
    retries_before_backoff,
    retry_interval_initial,
    retry_interval_max,
    broadcast_rooms,
):
    transport = MatrixTransport(
        config=MatrixTransportConfig(
            broadcast_rooms=broadcast_rooms,
            retries_before_backoff=retries_before_backoff,
            retry_interval_initial=retry_interval_initial,
            retry_interval_max=retry_interval_max,
            server=local_matrix_servers[0],
            available_servers=[local_matrix_servers[0]],
        ),
        environment=Environment.DEVELOPMENT,
    )
    transport.start(MockRaidenService(None), [], "")
    gevent.idle()

    ms_room_name = make_room_alias(transport.chain_id,
                                   MONITORING_BROADCASTING_ROOM)
    ms_room = transport._broadcast_rooms.get(ms_room_name)
    assert isinstance(ms_room, Room)

    ms_room.send_text = MagicMock(spec=ms_room.send_text)

    for i in range(5):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        transport._raiden_service.sign(message)
        transport.broadcast(MONITORING_BROADCASTING_ROOM, message)
    transport._schedule_new_greenlet(transport._broadcast_worker)

    gevent.idle()

    assert ms_room.send_text.call_count >= 1
    # messages could have been bundled
    call_args_str = " ".join(
        str(arg) for arg in ms_room.send_text.call_args_list)
    for i in range(5):
        assert f'"message_identifier": "{i}"' in call_args_str

    transport.stop()
    transport.greenlet.get()
Esempio n. 10
0
def test_matrix_send_global(local_matrix_servers, retries_before_backoff,
                            retry_interval, private_rooms, global_rooms):
    transport = MatrixTransport({
        "global_rooms":
        global_rooms + [MONITORING_BROADCASTING_ROOM],
        "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]],
        "private_rooms":
        private_rooms,
    })
    transport.start(MockRaidenService(None), MessageHandler(set()), "")
    gevent.idle()

    ms_room_name = make_room_alias(transport.chain_id,
                                   MONITORING_BROADCASTING_ROOM)
    ms_room = transport._global_rooms.get(ms_room_name)
    assert isinstance(ms_room, Room)

    ms_room.send_text = MagicMock(spec=ms_room.send_text)

    for i in range(5):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        transport._raiden_service.sign(message)
        transport.send_global(MONITORING_BROADCASTING_ROOM, message)
    transport._schedule_new_greenlet(transport._global_send_worker)

    gevent.idle()

    assert ms_room.send_text.call_count >= 1
    # messages could have been bundled
    call_args_str = " ".join(
        str(arg) for arg in ms_room.send_text.call_args_list)
    for i in range(5):
        assert f'"message_identifier": "{i}"' in call_args_str

    transport.stop()
    transport.get()
Esempio n. 11
0
def test_encoding_and_decoding():
    message_factories = (
        factories.LockedTransferProperties(),
        factories.RefundTransferProperties(),
        factories.LockExpiredProperties(),
        factories.UnlockProperties(),
    )
    messages = [factories.create(factory) for factory in message_factories]

    # TODO Handle these with factories once #5091 is implemented
    messages.append(
        Delivered(
            delivered_message_identifier=factories.make_message_identifier(),
            signature=factories.make_signature(),
        ))
    messages.append(
        Processed(
            message_identifier=factories.make_message_identifier(),
            signature=factories.make_signature(),
        ))
    messages.append(
        RevealSecret(
            message_identifier=factories.make_message_identifier(),
            secret=factories.make_secret(),
            signature=factories.make_signature(),
        ))
    messages.append(
        SecretRequest(
            message_identifier=factories.make_message_identifier(),
            payment_identifier=factories.make_payment_id(),
            secrethash=factories.make_secret_hash(),
            amount=factories.make_token_amount(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawRequest(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawConfirmation(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawExpired(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        PFSCapacityUpdate(
            canonical_identifier=factories.make_canonical_identifier(),
            updating_participant=factories.make_address(),
            other_participant=factories.make_address(),
            updating_nonce=factories.make_nonce(),
            other_nonce=factories.make_nonce(),
            updating_capacity=factories.make_token_amount(),
            other_capacity=factories.make_token_amount(),
            reveal_timeout=factories.make_uint64(),
            signature=factories.make_signature(),
        ))
    messages.append(
        PFSFeeUpdate(
            canonical_identifier=factories.make_canonical_identifier(),
            updating_participant=factories.make_address(),
            fee_schedule=factories.create(
                factories.FeeScheduleStateProperties()),
            timestamp=datetime.now(),
            signature=factories.make_signature(),
        ))
    messages.append(
        RequestMonitoring(
            reward_amount=factories.make_token_amount(),
            balance_proof=SignedBlindedBalanceProof.
            from_balance_proof_signed_state(
                factories.create(
                    factories.BalanceProofSignedStateProperties())),
            monitoring_service_contract_address=factories.make_address(),
            non_closing_participant=factories.make_address(),
            non_closing_signature=factories.make_signature(),
            signature=factories.make_signature(),
        ))

    for message in messages:
        serialized = MessageSerializer.serialize(message)
        deserialized = MessageSerializer.deserialize(serialized)
        assert deserialized == message
Esempio n. 12
0
def test_matrix_message_sync(matrix_transports):

    transport0, transport1 = matrix_transports

    received_messages = set()

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

    raiden_service1.handle_and_track_state_changes = MagicMock()

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

    latest_auth_data = f"{transport1._user_id}/{transport1._client.api.token}"
    update_transport_auth_data = ActionUpdateTransportAuthData(
        latest_auth_data)
    with gevent.Timeout(2):
        wait_assert(
            raiden_service1.handle_and_track_state_changes.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,
        canonical_identifier=factories.UNIT_CANONICAL_ID,
    )

    raiden0_queues = views.get_all_messagequeues(
        views.state_from_raiden(raiden_service0))
    raiden0_queues[queue_identifier] = []

    for i in range(5):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        raiden0_queues[queue_identifier].append(message)
        transport0._raiden_service.sign(message)
        transport0.send_async(queue_identifier, message)

    with Timeout(TIMEOUT_MESSAGE_RECEIVE):
        while not len(received_messages) == 10:
            gevent.sleep(0.1)

    assert len(received_messages) == 10

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

    # Clear out queue
    raiden0_queues[queue_identifier] = []

    transport1.stop()

    wait_for_peer_unreachable(transport0, transport1._raiden_service.address)

    assert latest_auth_data

    # Send more messages while the other end is offline
    for i in range(10, 15):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        raiden0_queues[queue_identifier].append(message)
        transport0._raiden_service.sign(message)
        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)
    transport1.start_health_check(transport0._raiden_service.address)

    with gevent.Timeout(TIMEOUT_MESSAGE_RECEIVE):
        while len(set(received_messages)) != 20:
            gevent.sleep(0.1)

    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)
def test_matrix_message_retry(
    local_matrix_servers,
    retry_interval_initial,
    retry_interval_max,
    retries_before_backoff,
    broadcast_rooms,
):
    """ 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 = factories.make_address()

    transport = MatrixTransport(
        config=MatrixTransportConfig(
            broadcast_rooms=broadcast_rooms,
            retries_before_backoff=retries_before_backoff,
            retry_interval_initial=retry_interval_initial,
            retry_interval_max=retry_interval_max,
            server=local_matrix_servers[0],
            available_servers=[local_matrix_servers[0]],
        ),
        environment=Environment.DEVELOPMENT,
    )
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)

    transport.start(raiden_service, [], None)
    transport.log = MagicMock()

    # Receiver is online
    transport._address_mgr._address_to_reachabilitystate[partner_address] = ReachabilityState(
        AddressReachability.REACHABLE, datetime.now()
    )

    queueid = QueueIdentifier(
        recipient=partner_address, canonical_identifier=CANONICAL_IDENTIFIER_UNORDERED_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(message_identifier=0, signature=EMPTY_SIGNATURE)
    transport._raiden_service.sign(message)
    chain_state.queueids_to_queues[queueid] = [message]
    retry_queue.enqueue_unordered(message)

    gevent.idle()
    assert transport._send_raw.call_count == 1

    # Receiver goes offline
    transport._address_mgr._address_to_reachabilitystate[partner_address] = ReachabilityState(
        AddressReachability.UNREACHABLE, datetime.now()
    )

    with gevent.Timeout(retry_interval_initial + 2):
        wait_assert(
            transport.log.debug.assert_called_with,
            "Partner not reachable. Skipping.",
            partner=to_checksum_address(partner_address),
            status=AddressReachability.UNREACHABLE,
        )

    # 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_mgr._address_to_reachabilitystate[partner_address] = ReachabilityState(
        AddressReachability.REACHABLE, datetime.now()
    )

    # Retrier should send the message again
    with gevent.Timeout(retry_interval_initial + 2):
        while transport._send_raw.call_count != 2:
            gevent.sleep(0.1)

    transport.stop()
    transport.greenlet.get()
Esempio n. 14
0
def test_unhandled_message(pathfinding_service_mock, log):
    unknown_message = Processed(MessageID(123), signature=EMPTY_SIGNATURE)
    unknown_message.sign(LocalSigner(PARTICIPANT1_PRIVKEY))

    pathfinding_service_mock.handle_message(unknown_message)
    assert log.has("Ignoring message", unknown_message=unknown_message)
Esempio n. 15
0
def test_matrix_message_retry(local_matrix_servers, private_rooms,
                              retry_interval, retries_before_backoff,
                              global_rooms):
    """ 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 = factories.make_address()

    transport = MatrixTransport({
        "global_rooms": global_rooms,
        "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]],
        "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_mgr._address_to_reachability[
        partner_address] = AddressReachability.REACHABLE

    queueid = QueueIdentifier(
        recipient=partner_address,
        canonical_identifier=CANONICAL_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(message_identifier=0, signature=EMPTY_SIGNATURE)
    transport._raiden_service.sign(message)
    chain_state.queueids_to_queues[queueid] = [message]
    retry_queue.enqueue_global(message)

    gevent.idle()
    assert transport._send_raw.call_count == 1

    # Receiver goes offline
    transport._address_mgr._address_to_reachability[
        partner_address] = AddressReachability.UNREACHABLE

    with gevent.Timeout(retry_interval + 2):
        wait_assert(
            transport.log.debug.assert_called_with,
            "Partner not reachable. Skipping.",
            partner=to_checksum_address(partner_address),
            status=AddressReachability.UNREACHABLE,
        )

    # 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_mgr._address_to_reachability[
        partner_address] = AddressReachability.REACHABLE

    # Retrier should send the message again
    with gevent.Timeout(retry_interval + 2):
        while transport._send_raw.call_count != 2:
            gevent.sleep(0.1)

    transport.stop()
    transport.get()
def test_transport_does_not_receive_broadcast_rooms_updates(matrix_transports):
    """ Ensure that matrix server-side filters take effect on sync for broadcast room content.

    The test sets up 3 transports where:
    Transport0 sends a message to the PFS broadcast room.
    Transport1 has an active sync filter ID that filters out broadcast room messages.
    Transport2 has NO active sync filter so it receives everything.

    The test should wait for Transport0 to send a message and then
    verify that Transport2 has received the message while Transport1
    did not.
    """
    raiden_service0 = MockRaidenService(None)
    raiden_service1 = MockRaidenService(None)
    raiden_service2 = MockRaidenService(None)

    transport0, transport1, transport2 = matrix_transports

    received_sync_events: Dict[str, List[Dict[str, Any]]] = {"t1": [], "t2": []}

    def _handle_responses(
        name: str, responses: List[Dict[str, Any]], first_sync: bool = False
    ):  # pylint: disable=unused-argument
        for response in responses:
            joined_rooms = response.get("rooms", {}).get("join", {})
            for joined_room in joined_rooms.values():
                timeline_events = joined_room.get("timeline").get("events", [])
                message_events = [
                    event for event in timeline_events if event["type"] == "m.room.message"
                ]
                received_sync_events[name].extend(message_events)

    # Replace the transport's handle_response method
    # Should be able to detect if sync delivered a message
    transport1._client._handle_responses = partial(_handle_responses, "t1")
    transport2._client._handle_responses = partial(_handle_responses, "t2")

    transport0.start(raiden_service0, [], None)
    transport1.start(raiden_service1, [], None)
    transport2.start(raiden_service2, [], None)

    pfs_broadcast_room_alias = make_room_alias(transport0.chain_id, PATH_FINDING_BROADCASTING_ROOM)
    pfs_broadcast_room_t0 = transport0._broadcast_rooms[pfs_broadcast_room_alias]

    # Get the sync helper to control flow of asynchronous syncs
    sync_progress1 = transport1._client.sync_progress
    sync_progress2 = transport2._client.sync_progress

    # Reset transport2 sync filter identifier so that
    # we can receive broadcast messages
    assert transport2._client._sync_filter_id is not None
    transport2._client._sync_filter_id = None

    # get the last sync tokens to control the processed state later
    last_synced_token1 = sync_progress1.last_synced
    # for T2 we need to make sure that the current sync used the filter reset -> wait()
    last_synced_token2 = sync_progress2.synced_event.wait()[0]
    # Send another message to the broadcast room, if transport1 listens on the room it will
    # throw an exception
    message = Processed(message_identifier=1, signature=EMPTY_SIGNATURE)
    message_text = MessageSerializer.serialize(message)
    pfs_broadcast_room_t0.send_text(message_text)

    # wait for the current tokens to be processed + 1 additional sync
    # this must be done because the message should be in the sync after the stored token
    sync_progress1.wait_for_processed(last_synced_token1, 1)
    sync_progress2.wait_for_processed(last_synced_token2, 1)

    # Transport2 should have received the message
    assert received_sync_events["t2"]
    event_body = received_sync_events["t2"][0]["content"]["body"]
    assert message_text == event_body

    # Transport1 used the filter so nothing was received
    assert not received_sync_events["t1"]
def test_matrix_message_sync(matrix_transports):

    transport0, transport1 = matrix_transports

    transport0_messages = set()
    transport1_messages = set()

    transport0_message_handler = MessageHandler(transport0_messages)
    transport1_message_handler = MessageHandler(transport1_messages)

    raiden_service0 = MockRaidenService(transport0_message_handler)
    raiden_service1 = MockRaidenService(transport1_message_handler)

    raiden_service1.handle_and_track_state_changes = MagicMock()

    transport0.start(raiden_service0, [], None)
    transport1.start(raiden_service1, [], None)

    transport0.immediate_health_check_for(transport1._raiden_service.address)
    transport1.immediate_health_check_for(transport0._raiden_service.address)

    queue_identifier = QueueIdentifier(
        recipient=transport1._raiden_service.address,
        canonical_identifier=factories.UNIT_CANONICAL_ID,
    )

    raiden0_queues = views.get_all_messagequeues(views.state_from_raiden(raiden_service0))
    raiden0_queues[queue_identifier] = []

    for i in range(5):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        raiden0_queues[queue_identifier].append(message)
        transport0._raiden_service.sign(message)
        transport0.send_async([MessagesQueue(queue_identifier, [message])])

    with Timeout(TIMEOUT_MESSAGE_RECEIVE):
        while not len(transport0_messages) == 5:
            gevent.sleep(0.1)

        while not len(transport1_messages) == 5:
            gevent.sleep(0.1)

    # transport1 receives the `Processed` messages sent by transport0
    for i in range(5):
        assert any(m.message_identifier == i for m in transport1_messages)

    # transport0 answers with a `Delivered` for each `Processed`
    for i in range(5):
        assert any(m.delivered_message_identifier == i for m in transport0_messages)

    # Clear out queue
    raiden0_queues[queue_identifier] = []

    transport1.stop()

    wait_for_peer_unreachable(transport0, transport1._raiden_service.address)

    # Send more messages while the other end is offline
    for i in range(10, 15):
        message = Processed(message_identifier=i, signature=EMPTY_SIGNATURE)
        raiden0_queues[queue_identifier].append(message)
        transport0._raiden_service.sign(message)
        transport0.send_async([MessagesQueue(queue_identifier, [message])])

    # Should fetch the 5 messages sent while transport1 was offline
    transport1.start(transport1._raiden_service, [], None)
    transport1.immediate_health_check_for(transport0._raiden_service.address)

    with gevent.Timeout(TIMEOUT_MESSAGE_RECEIVE):
        while len(transport1_messages) != 10:
            gevent.sleep(0.1)

        while len(transport0_messages) != 10:
            gevent.sleep(0.1)

    # transport1 receives the 5 new `Processed` messages sent by transport0
    for i in range(10, 15):
        assert any(m.message_identifier == i for m in transport1_messages)

    # transport0 answers with a `Delivered` for each one of the new `Processed`
    for i in range(10, 15):
        assert any(m.delivered_message_identifier == i for m in transport0_messages)
Esempio n. 18
0
def test_message_handler():
    """
    Test for MessageHandler.on_message and the different methods it dispatches into.
    Each of them results in a call to a RaidenService method, which is checked with a Mock.
    """

    our_address = factories.make_address()
    sender_privkey, sender = factories.make_privkey_address()
    signer = LocalSigner(sender_privkey)
    message_handler = MessageHandler()
    mock_raiden = Mock(
        address=our_address, default_secret_registry=Mock(is_secret_registered=lambda **_: False)
    )

    properties = factories.LockedTransferProperties(sender=sender, pkey=sender_privkey)
    locked_transfer = factories.create(properties)
    message_handler.on_message(mock_raiden, locked_transfer)
    assert_method_call(mock_raiden, "mediate_mediated_transfer", locked_transfer)

    locked_transfer_for_us = factories.create(factories.replace(properties, target=our_address))
    message_handler.on_message(mock_raiden, locked_transfer_for_us)
    assert_method_call(mock_raiden, "target_mediated_transfer", locked_transfer_for_us)

    mock_raiden.default_secret_registry.is_secret_registered = lambda **_: True
    message_handler.on_message(mock_raiden, locked_transfer)
    assert not mock_raiden.mediate_mediated_transfer.called
    assert not mock_raiden.target_mediated_transfer.called
    mock_raiden.default_secret_registry.is_secret_registered = lambda **_: False

    params = dict(
        payment_identifier=13, amount=14, expiration=15, secrethash=factories.UNIT_SECRETHASH
    )
    secret_request = SecretRequest(
        message_identifier=16, signature=factories.EMPTY_SIGNATURE, **params
    )
    secret_request.sign(signer)
    receive = ReceiveSecretRequest(sender=sender, **params)
    message_handler.on_message(mock_raiden, secret_request)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    secret = factories.make_secret()
    reveal_secret = RevealSecret(
        message_identifier=100, signature=factories.EMPTY_SIGNATURE, secret=secret
    )
    reveal_secret.sign(signer)
    receive = ReceiveSecretReveal(sender=sender, secret=secret)
    message_handler.on_message(mock_raiden, reveal_secret)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    properties: factories.UnlockProperties = factories.create_properties(
        factories.UnlockProperties()
    )
    unlock = factories.create(properties)
    unlock.sign(signer)
    balance_proof = factories.make_signed_balance_proof_from_unsigned(
        factories.create(properties.balance_proof), signer, unlock.message_hash
    )
    receive = ReceiveUnlock(
        message_identifier=properties.message_identifier,
        secret=properties.secret,
        balance_proof=balance_proof,
        sender=sender,
    )
    message_handler.on_message(mock_raiden, unlock)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    properties: factories.LockExpiredProperties = factories.create_properties(
        factories.LockExpiredProperties()
    )
    lock_expired = factories.create(properties)
    lock_expired.sign(signer)
    balance_proof = factories.make_signed_balance_proof_from_unsigned(
        factories.create(properties.balance_proof), signer, lock_expired.message_hash
    )
    receive = ReceiveLockExpired(
        balance_proof=balance_proof,
        message_identifier=properties.message_identifier,
        secrethash=properties.secrethash,  # pylint: disable=no-member
        sender=sender,
    )
    message_handler.on_message(mock_raiden, lock_expired)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    delivered = Delivered(delivered_message_identifier=1, signature=factories.EMPTY_SIGNATURE)
    delivered.sign(signer)
    receive = ReceiveDelivered(message_identifier=1, sender=sender)
    message_handler.on_message(mock_raiden, delivered)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    processed = Processed(message_identifier=42, signature=factories.EMPTY_SIGNATURE)
    processed.sign(signer)
    receive = ReceiveProcessed(message_identifier=42, sender=sender)
    message_handler.on_message(mock_raiden, processed)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])
def ping_pong_message_success(transport0, transport1):
    queueid0 = QueueIdentifier(
        recipient=transport0._raiden_service.address,
        canonical_identifier=CANONICAL_IDENTIFIER_UNORDERED_QUEUE,
    )

    queueid1 = QueueIdentifier(
        recipient=transport1._raiden_service.address,
        canonical_identifier=CANONICAL_IDENTIFIER_UNORDERED_QUEUE,
    )

    transport0_raiden_queues = views.get_all_messagequeues(
        views.state_from_raiden(transport0._raiden_service)
    )
    transport1_raiden_queues = views.get_all_messagequeues(
        views.state_from_raiden(transport1._raiden_service)
    )

    transport0_raiden_queues[queueid1] = []
    transport1_raiden_queues[queueid0] = []

    received_messages0 = transport0._raiden_service.message_handler.bag
    received_messages1 = transport1._raiden_service.message_handler.bag

    msg_id = random.randint(1e5, 9e5)

    ping_message = Processed(message_identifier=msg_id, signature=EMPTY_SIGNATURE)
    pong_message = Delivered(delivered_message_identifier=msg_id, signature=EMPTY_SIGNATURE)

    transport0_raiden_queues[queueid1].append(ping_message)

    transport0._raiden_service.sign(ping_message)
    transport1._raiden_service.sign(pong_message)
    transport0.send_async([MessagesQueue(queueid1, [ping_message])])

    with Timeout(TIMEOUT_MESSAGE_RECEIVE, exception=False):
        all_messages_received = False
        while not all_messages_received:
            all_messages_received = (
                ping_message in received_messages1 and pong_message in received_messages0
            )
            gevent.sleep(0.1)
    assert ping_message in received_messages1
    assert pong_message in received_messages0

    transport0_raiden_queues[queueid1].clear()
    transport1_raiden_queues[queueid0].append(ping_message)

    transport0._raiden_service.sign(pong_message)
    transport1._raiden_service.sign(ping_message)
    transport1.send_async([MessagesQueue(queueid0, [ping_message])])

    with Timeout(TIMEOUT_MESSAGE_RECEIVE, exception=False):
        all_messages_received = False
        while not all_messages_received:
            all_messages_received = (
                ping_message in received_messages0 and pong_message in received_messages1
            )
            gevent.sleep(0.1)
    assert ping_message in received_messages0
    assert pong_message in received_messages1

    transport1_raiden_queues[queueid0].clear()

    return all_messages_received
Esempio n. 20
0
    factories.RefundTransferProperties(),
    factories.LockExpiredProperties(),
    factories.UnlockProperties(),
)
messages = [factories.create(factory) for factory in message_factories]

# TODO Handle these with factories once #5091 is implemented
messages.append(
    Delivered(
        delivered_message_identifier=factories.make_message_identifier(),
        signature=factories.make_signature(),
    )
)
messages.append(
    Processed(
        message_identifier=factories.make_message_identifier(),
        signature=factories.make_signature(),
    )
)
messages.append(
    RevealSecret(
        message_identifier=factories.make_message_identifier(),
        secret=factories.make_secret(),
        signature=factories.make_signature(),
    )
)
messages.append(
    SecretRequest(
        message_identifier=factories.make_message_identifier(),
        payment_identifier=factories.make_payment_id(),
        secrethash=factories.make_secret_hash(),
        amount=factories.make_payment_amount(),