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