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
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
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}")
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)
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() == []
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]
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)
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()
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()
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
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()
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)
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)
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
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(),