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_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()
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()
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()