def restart_network(raiden_network, retry_timeout): for app in raiden_network: app.stop() wait_network = [ gevent.spawn(restart_app, app) for app in raiden_network ] gevent.wait(wait_network) new_network = [ greenlet.get() for greenlet in wait_network ] # The tests assume the nodes are available to transfer for app0, app1 in combinations(new_network, 2): waiting.wait_for_healthy( app0.raiden, app1.raiden.address, retry_timeout, ) return new_network
def test_recovery_blockchain_events(raiden_network, restart_node, token_addresses, network_wait): """ Close one of the two raiden apps that have a channel between them, have the counterparty close the channel and then make sure the restarted app sees the change """ app0, app1 = raiden_network token_address = token_addresses[0] app0.raiden.stop() new_transport = MatrixTransport( config=app0.raiden.config.transport, environment=app0.raiden.config.environment_type) app1_api = RaidenAPI(app1.raiden) app1_api.channel_close( registry_address=app0.raiden.default_registry.address, token_address=token_address, partner_address=app0.raiden.address, ) app0.stop() raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() 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=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, routing_mode=RoutingMode.PRIVATE, ) del app0 # from here on the app0_restart should be used restart_node(app0_restart) wal = app0_restart.raiden.wal assert wal # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy(app0_restart.raiden, app1.raiden.address, network_wait) waiting.wait_for_healthy(app1.raiden, app0_restart.raiden.address, network_wait) restarted_state_changes = wal.storage.get_statechanges_by_range( RANGE_ALL_STATE_CHANGES) assert search_for_item(restarted_state_changes, ContractReceiveChannelClosed, {})
def wait_for_usable_channel( raiden: RaidenService, partner_address: Address, token_network_registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, our_deposit: TokenAmount, partner_deposit: TokenAmount, retry_timeout: float = DEFAULT_RETRY_TIMEOUT, ) -> None: """ Wait until the channel from app0 to app1 is usable. The channel and the deposits are registered, and the partner network state is reachable. """ waiting.wait_for_newchannel( raiden=raiden, token_network_registry_address=token_network_registry_address, token_address=token_address, partner_address=partner_address, retry_timeout=retry_timeout, ) # wait for our deposit waiting.wait_for_participant_deposit( raiden=raiden, token_network_registry_address=token_network_registry_address, token_address=token_address, partner_address=partner_address, target_address=raiden.address, target_balance=our_deposit, retry_timeout=retry_timeout, ) # wait for the partner deposit waiting.wait_for_participant_deposit( raiden=raiden, token_network_registry_address=token_network_registry_address, token_address=token_address, partner_address=partner_address, target_address=partner_address, target_balance=partner_deposit, retry_timeout=retry_timeout, ) waiting.wait_for_healthy(raiden=raiden, node_address=partner_address, retry_timeout=retry_timeout)
def wait_for_usable_channel( app0, app1, registry_address, token_address, our_deposit, partner_deposit, events_poll_timeout=0.5, ): """ Wait until the channel from app0 to app1 is usable. The channel and the deposits are registered, and the partner network state is reachable. """ waiting.wait_for_newchannel( app0.raiden, registry_address, token_address, app1.raiden.address, events_poll_timeout, ) waiting.wait_for_participant_newbalance( app0.raiden, registry_address, token_address, app1.raiden.address, app0.raiden.address, our_deposit, events_poll_timeout, ) waiting.wait_for_participant_newbalance( app0.raiden, registry_address, token_address, app1.raiden.address, app1.raiden.address, partner_deposit, events_poll_timeout, ) waiting.wait_for_healthy( app0.raiden, app1.raiden.address, events_poll_timeout, )
def wait_for_usable_channel( app0, app1, registry_address, token_address, our_deposit, partner_deposit, retry_timeout=DEFAULT_RETRY_TIMEOUT, ): """ Wait until the channel from app0 to app1 is usable. The channel and the deposits are registered, and the partner network state is reachable. """ waiting.wait_for_newchannel( app0.raiden, registry_address, token_address, app1.raiden.address, retry_timeout, ) waiting.wait_for_participant_newbalance( app0.raiden, registry_address, token_address, app1.raiden.address, app0.raiden.address, our_deposit, retry_timeout, ) waiting.wait_for_participant_newbalance( app0.raiden, registry_address, token_address, app1.raiden.address, app1.raiden.address, partner_deposit, retry_timeout, ) waiting.wait_for_healthy( app0.raiden, app1.raiden.address, retry_timeout, )
def restart_network(raiden_network: List[App], restart_node: RestartNode, retry_timeout: float) -> List[App]: for app in raiden_network: app.stop() wait_network = (gevent.spawn(restart_app, app, restart_node) for app in raiden_network) gevent.joinall(set(wait_network), raise_error=True) new_network = [greenlet.get() for greenlet in wait_network] # The tests assume the nodes are available to transfer for app0, app1 in combinations(new_network, 2): waiting.wait_for_healthy(app0.raiden, app1.raiden.address, retry_timeout) return new_network
def test_recovery_blockchain_events( raiden_network, token_addresses, network_wait, skip_if_not_udp, # pylint: disable=unused-argument ): """ Close one of the two raiden apps that have a channel between them, have the counterparty close the channel and then make sure the restarted app sees the change """ app0, app1 = raiden_network token_address = token_addresses[0] app0.raiden.stop() host_port = ( app0.raiden.config["transport"]["udp"]["host"], app0.raiden.config["transport"]["udp"]["port"], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config["transport"]["udp"], ) app1_api = RaidenAPI(app1.raiden) app1_api.channel_close( registry_address=app0.raiden.default_registry.address, token_address=token_address, partner_address=app0.raiden.address, ) app0.stop() gevent.sleep(1) 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_secret_registry=app0.raiden.default_secret_registry, default_service_registry=app0.raiden.default_service_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) del app0 # from here on the app0_restart should be used app0_restart.raiden.start() # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy(app0_restart.raiden, app1.raiden.address, network_wait) waiting.wait_for_healthy(app1.raiden, app0_restart.raiden.address, network_wait) restarted_state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier( 0, "latest") assert search_for_item(restarted_state_changes, ContractReceiveChannelClosed, {})
def test_recovery_blockchain_events( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): """ Close one of the two raiden apps that have a channel between them, have the counterparty close the channel and then make sure the restarted app sees the change """ app0, app1 = raiden_network token_address = token_addresses[0] app0.raiden.stop() host_port = (app0.raiden.config['host'], app0.raiden.config['port']) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport'], ) app1_api = RaidenAPI(app1.raiden) app1_api.channel_close( registry_address=app0.raiden.default_registry.address, token_address=token_address, partner_address=app0.raiden.address, ) app0.stop() import gevent gevent.sleep(1) app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, discovery=app0.raiden.discovery, ) del app0 # from here on the app0_restart should be used # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) restarted_state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier( 0, 'latest', ) assert must_contain_entry(restarted_state_changes, ContractReceiveChannelClosed, {})
def test_send_queued_messages( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_matrix, ): """Test re-sending of undelivered messages on node restart""" app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # stop app1 - direct transfer must be left unconfirmed app1.stop() # make a few transfers from app0 to app2 amount = 1 spent_amount = 7 for _ in range(spent_amount): direct_transfer( app0, app1, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) # restart app0 app0.raiden.stop() new_transport = MatrixTransport( app0.raiden.config['transport']['matrix'], ) app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app1.start() app0_restart.start() waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) exception = RuntimeError('Timeout while waiting for new channel') with gevent.Timeout(5, exception=exception): waiting.wait_for_newchannel( app0_restart.raiden, payment_network_id, token_address, app1.raiden.address, network_wait, ) exception = RuntimeError('Timeout while waiting for balance update for app0') with gevent.Timeout(30, exception=exception): waiting.wait_for_payment_balance( app0_restart.raiden, payment_network_id, token_address, app1.raiden.address, app1.raiden.address, spent_amount, network_wait, ) waiting.wait_for_payment_balance( app1.raiden, payment_network_id, token_address, app0_restart.raiden.address, app1.raiden.address, spent_amount, network_wait, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], )
def test_payment_statuses_are_restored( # pylint: disable=unused-argument raiden_network, token_addresses, network_wait): """ Test that when the Raiden is restarted, the dictionary of `targets_to_identifiers_to_statuses` is populated before the transport is started. This should happen because if a client gets restarted during a transfer cycle, once restarted, the client will proceed with the cycle until the transfer is successfully sent. However, the dictionary `targets_to_identifiers_to_statuses` will not contain the payment identifiers that were originally registered when the previous client started the transfers. Related issue: https://github.com/raiden-network/raiden/issues/3432 """ app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) token_network_registry_address = app0.raiden.default_registry.address token_network_address = views.get_token_network_address_by_token_address( chain_state, token_network_registry_address, token_address) # make a few transfers from app0 to app1 amount = 1 spent_amount = TokenAmount(7) for identifier in range(spent_amount): # Make sure the transfer is not completed secret = make_secret(identifier) app0.raiden.raiden_event_handler.hold(SendSecretReveal, {"secret": secret}) identifier = identifier + 1 payment_status = app0.raiden.mediated_transfer_async( token_network_address=token_network_address, amount=amount, target=app1.raiden.address, identifier=identifier, secret=secret, ) assert payment_status.payment_identifier == identifier 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_secret_registry=app0.raiden.default_secret_registry, default_service_registry=app0.raiden.default_service_registry, default_one_to_n_address=app0.raiden.default_one_to_n_address, default_msc_address=app0.raiden.default_msc_address, transport=MatrixTransport(app0.raiden.config["transport"]["matrix"]), raiden_event_handler=RaidenEventHandler(), message_handler=MessageHandler(), routing_mode=RoutingMode.PRIVATE, ) app0.stop() del app0 # from here on the app0_restart should be used # stop app1 to make sure that we don't complete the transfers before our checks app1.stop() app0_restart.start() # Check that the payment statuses were restored properly after restart for identifier in range(spent_amount): identifier = PaymentID(identifier + 1) mapping = app0_restart.raiden.targets_to_identifiers_to_statuses status = mapping[app1.raiden.address][identifier] assert status.amount == 1 assert status.payment_identifier == identifier assert status.token_network_address == token_network_address app1.start() # now that our checks are done start app1 again with watch_for_unlock_failures(*raiden_network): waiting.wait_for_healthy(app0_restart.raiden, app1.raiden.address, network_wait) waiting.wait_for_payment_balance( raiden=app1.raiden, token_network_registry_address=token_network_registry_address, token_address=token_address, partner_address=app0_restart.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) # Check that payments are completed after both nodes come online after restart for identifier in range(spent_amount): assert raiden_events_search_for_item( app0_restart.raiden, EventPaymentSentSuccess, { "identifier": identifier + 1, "amount": 1 }, )
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = (app0.raiden.config['host'], app0.raiden.config['port']) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport'], ) app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used assert_synched_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synched_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) mediated_transfer( app2, app0_restart, token_network_identifier, amount, timeout=network_wait * number_of_nodes * 2, ) mediated_transfer( app0_restart, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes * 2, ) assert_synched_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synched_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] app2_wait_for = WaitForMessage() app2.raiden.message_handler = app2_wait_for chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = ( app0.raiden.config['transport']['udp']['host'], app0.raiden.config['transport']['udp']['port'], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport']['udp'], ) 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_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app0_restart.start() assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) identifier = create_default_identifier() wait_for_payment = app2_wait_for.wait_for_message(Secret, {'payment_identifier': identifier}) mediated_transfer( app2, app0_restart, token_network_identifier, amount, timeout=network_wait * number_of_nodes * 2, ) mediated_transfer( initiator_app=app0_restart, target_app=app2, token_network_identifier=token_network_identifier, amount=amount, identifier=identifier, timeout=network_wait * number_of_nodes * 2, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) wait_for_payment.wait() assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )
def test_recovery_blockchain_events( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): """ Close one of the two raiden apps that have a channel between them, have the counterparty close the channel and then make sure the restarted app sees the change """ app0, app1 = raiden_network token_address = token_addresses[0] app0.raiden.stop() host_port = ( app0.raiden.config['transport']['udp']['host'], app0.raiden.config['transport']['udp']['port'], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport']['udp'], ) app1_api = RaidenAPI(app1.raiden) app1_api.channel_close( registry_address=app0.raiden.default_registry.address, token_address=token_address, partner_address=app0.raiden.address, ) app0.stop() import gevent gevent.sleep(1) 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_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) del app0 # from here on the app0_restart should be used app0_restart.raiden.start() # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) restarted_state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier( 0, 'latest', ) assert must_contain_entry(restarted_state_changes, ContractReceiveChannelClosed, {})
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, # pylint: disable=unused-argument ): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 identifier = 0 for identifier in range(spent_amount): transfer_and_assert_path( path=raiden_network, token_address=token_address, amount=amount, identifier=identifier, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = ( app0.raiden.config["transport"]["udp"]["host"], app0.raiden.config["transport"]["udp"]["port"], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config["transport"]["udp"], ) raiden_event_handler = RaidenEventHandler() message_handler = WaitForMessage() app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, default_service_registry=app0.raiden.default_service_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app0_restart.start() assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy(app0_restart.raiden, app1.raiden.address, network_wait) waiting.wait_for_healthy(app1.raiden, app0_restart.raiden.address, network_wait) transfer( initiator_app=app2, target_app=app0_restart, token_address=token_address, amount=amount, identifier=create_default_identifier(), timeout=network_wait * number_of_nodes * 2, ) transfer( initiator_app=app0_restart, target_app=app2, token_address=token_address, amount=amount, identifier=create_default_identifier(), timeout=network_wait * number_of_nodes * 2, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )
def test_participant_selection(raiden_network, token_addresses): registry_address = raiden_network[0].raiden.default_registry.address # pylint: disable=too-many-locals token_address = token_addresses[0] # connect the first node (will register the token if necessary) RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=100, ) # Test invalid argument values with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=-1, ) with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=100, joinable_funds_target=2, ) with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=100, joinable_funds_target=-1, ) # connect the other nodes connect_greenlets = [ gevent.spawn( RaidenAPI(app.raiden).token_network_connect, registry_address, token_address, 100, ) for app in raiden_network[1:] ] gevent.wait(connect_greenlets) token_network_registry_address = views.get_token_network_identifier_by_token_address( views.state_from_raiden(raiden_network[0].raiden), payment_network_id=registry_address, token_address=token_address, ) connection_managers = [ app.raiden.connection_manager_for_token_network( token_network_registry_address, ) for app in raiden_network ] unsaturated_connection_managers = connection_managers[:] exception = AssertionError('Unsaturated connection managers', unsaturated_connection_managers) with gevent.Timeout(120, exception): while unsaturated_connection_managers: for manager in unsaturated_connection_managers: if is_manager_saturated(manager, registry_address, token_address): unsaturated_connection_managers.remove(manager) gevent.sleep(1) assert saturated_count( connection_managers, registry_address, token_address, ) == len(connection_managers) # ensure unpartitioned network for app in raiden_network: node_state = views.state_from_raiden(app.raiden) network_state = views.get_token_network_by_token_address( node_state, registry_address, token_address, ) assert network_state is not None for target in raiden_network: if target.raiden.address == app.raiden.address: continue routes = routing.get_best_routes( chain_state=node_state, token_network_id=network_state.address, from_address=app.raiden.address, to_address=target.raiden.address, amount=1, previous_address=None, config={}, ) assert routes is not None # create a transfer to the leaving node, so we have a channel to settle for app in raiden_network: sender = app.raiden sender_channel = next( (channel_state for channel_state in RaidenAPI(sender).get_channel_list( registry_address=registry_address, token_address=token_address, ) if channel_state.our_state.contract_balance > 0 and channel_state.partner_state.contract_balance > 0), None) # choose a fully funded channel from sender if sender_channel: break registry_address = sender.default_registry.address receiver = next( app.raiden for app in raiden_network if app.raiden.address == sender_channel.partner_state.address) # assert there is a direct channel receiver -> sender (vv) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert len(receiver_channel) == 1 receiver_channel = receiver_channel[0] exception = ValueError('partner not reachable') with gevent.Timeout(30, exception=exception): waiting.wait_for_healthy(sender, receiver.address, 1) amount = 1 RaidenAPI(sender).transfer_and_wait( registry_address, token_address, amount, receiver.address, transfer_timeout=10, ) exception = ValueError('timeout while waiting for incoming transaction') with gevent.Timeout(30, exception=exception): wait_for_transaction( receiver, registry_address, token_address, sender.address, ) # test `leave()` method connection_manager = connection_managers[0] timeout = (sender_channel.settle_timeout * connection_manager.raiden.chain.estimate_blocktime() * 10) assert timeout > 0 exception = ValueError('timeout while waiting for leave') with gevent.Timeout(timeout, exception=exception): # sender leaves the network RaidenAPI(sender).token_network_leave( registry_address, token_address, ) before_block = connection_manager.raiden.chain.block_number() wait_blocks = sender_channel.settle_timeout + 10 # wait until both chains are synced? connection_manager.raiden.chain.wait_until_block( target_block_number=before_block + wait_blocks, ) receiver.chain.wait_until_block(target_block_number=before_block + wait_blocks, ) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) # because of timing, channel may already have been cleaned assert not receiver_channel or receiver_channel[ 0].settle_transaction is not None
def test_send_queued_messages( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_matrix, ): """Test re-sending of undelivered messages on node restart""" app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) with dont_handle_node_change_network_state(): # stop app1 - transfer must be left unconfirmed app1.stop() # make a few transfers from app0 to app1 amount = 1 spent_amount = 7 identifier = 1 for _ in range(spent_amount): app0.raiden.mediated_transfer_async( token_network_identifier=token_network_identifier, amount=amount, target=app1.raiden.address, identifier=identifier, ) identifier += 1 # restart app0 app0.raiden.stop() new_transport = MatrixTransport( app0.raiden.config['transport']['matrix'], ) 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_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app1.start() app0_restart.start() waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) exception = RuntimeError('Timeout while waiting for new channel') with gevent.Timeout(5, exception=exception): waiting.wait_for_newchannel( raiden=app0_restart.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app1.raiden.address, retry_timeout=network_wait, ) exception = RuntimeError('Timeout while waiting for balance update for app0') with gevent.Timeout(30, exception=exception): waiting.wait_for_payment_balance( raiden=app0_restart.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app1.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) waiting.wait_for_payment_balance( raiden=app1.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app0_restart.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], )
def run_test_payment_statuses_are_restored( raiden_network, token_addresses, network_wait, ): app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) app0.event_handler = HoldRaidenEvent() app0.event_handler.hold(SendSecretReveal, {}) # make a few transfers from app0 to app1 amount = 1 spent_amount = 7 identifier = 1 for identifier in range(spent_amount): identifier = identifier + 1 payment_status = app0.raiden.mediated_transfer_async( token_network_identifier=token_network_identifier, amount=amount, target=app1.raiden.address, identifier=identifier, ) assert payment_status.payment_identifier == identifier 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_secret_registry=app0.raiden.default_secret_registry, default_service_registry=app0.raiden.default_service_registry, transport=MatrixTransport(app0.raiden.config['transport']['matrix'], ), raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used # stop app1 to make sure that we don't complete the transfers before our checks app1.stop() app0_restart.start() # Check that the payment statuses were restored properly after restart for identifier in range(spent_amount): identifier = identifier + 1 mapping = app0_restart.raiden.targets_to_identifiers_to_statuses status = mapping[app1.raiden.address][identifier] assert status.amount == 1 assert status.payment_identifier == identifier assert status.token_network_identifier == token_network_identifier app1.start() # now that our checks are done start app1 again waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_payment_balance( raiden=app1.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app0_restart.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) # Check that payments are completed after both nodes come online after restart for identifier in range(spent_amount): assert raiden_events_search_for_item( app0_restart.raiden, EventPaymentSentSuccess, { 'identifier': identifier + 1, 'amount': 1 }, )
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait ): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) token_network_registry_address = app0.raiden.default_registry.address token_network_address = views.get_token_network_address_by_token_address( chain_state, token_network_registry_address, token_address ) assert token_network_address # make a few transfers from app0 to app2 amount = PaymentAmount(1) spent_amount = deposit - 2 for identifier in range(spent_amount): transfer_and_assert_path( path=raiden_network, token_address=token_address, amount=amount, identifier=PaymentID(identifier), timeout=network_wait * number_of_nodes, ) app0.stop() waiting.wait_for_network_state( app1.raiden, app0.raiden.address, NetworkState.UNREACHABLE, network_wait ) app0.start() assert_synced_channel_state( token_network_address, app0, deposit - spent_amount, [], app1, deposit + spent_amount, [] ) assert_synced_channel_state( token_network_address, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [] ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy(app0.raiden, app1.raiden.address, network_wait) waiting.wait_for_healthy(app1.raiden, app0.raiden.address, network_wait) transfer_and_assert_path( path=raiden_network[::-1], token_address=token_address, amount=amount, identifier=create_default_identifier(), timeout=network_wait * number_of_nodes, ) transfer_and_assert_path( path=raiden_network, token_address=token_address, amount=amount, identifier=create_default_identifier(), timeout=network_wait * number_of_nodes, ) assert_succeeding_transfer_invariants( token_network_address, app0, deposit - spent_amount, [], app1, deposit + spent_amount, [] ) assert_succeeding_transfer_invariants( token_network_address, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [] )
def test_participant_selection(raiden_network, token_addresses, skip_if_tester): registry_address = raiden_network[0].raiden.default_registry.address # pylint: disable=too-many-locals token_address = token_addresses[0] # connect the first node (will register the token if necessary) RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address, token_address, 100, ) # connect the other nodes connect_greenlets = [ gevent.spawn( RaidenAPI(app.raiden).token_network_connect, registry_address, token_address, 100, ) for app in raiden_network[1:] ] gevent.wait(connect_greenlets) token_network_registry_address = views.get_token_network_identifier_by_token_address( views.state_from_raiden(raiden_network[0].raiden), payment_network_id=registry_address, token_address=token_address, ) connection_managers = [ app.raiden.connection_manager_for_token_network( token_network_registry_address, ) for app in raiden_network ] assert wait_for_saturated( connection_managers, registry_address, token_address, ) is True assert saturated_count( connection_managers, registry_address, token_address, ) == len(connection_managers) # ensure unpartitioned network for app in raiden_network: node_state = views.state_from_raiden(app.raiden) network_state = views.get_token_network_by_token_address( node_state, registry_address, token_address, ) assert network_state is not None for target in raiden_network: if target.raiden.address == app.raiden.address: continue routes = routing.get_best_routes( node_state, network_state.address, app.raiden.address, target.raiden.address, 1, None, ) assert routes is not None # create a transfer to the leaving node, so we have a channel to settle sender = raiden_network[-1].raiden receiver = raiden_network[0].raiden registry_address = sender.default_registry.address # assert there is a direct channel receiver -> sender (vv) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert len(receiver_channel) == 1 receiver_channel = receiver_channel[0] # assert there is a direct channel sender -> receiver sender_channel = RaidenAPI(sender).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=receiver.address, ) assert len(sender_channel) == 1 sender_channel = sender_channel[0] exception = ValueError('partner not reachable') with gevent.Timeout(30, exception=exception): waiting.wait_for_healthy(sender, receiver.address, 1) amount = 1 RaidenAPI(sender).transfer_and_wait( registry_address, token_address, amount, receiver.address, transfer_timeout=10, ) exception = ValueError('timeout while waiting for incoming transaction') with gevent.Timeout(30, exception=exception): wait_for_transaction( receiver, registry_address, token_address, sender.address, ) # test `leave()` method connection_manager = connection_managers[0] timeout = ( sender_channel.settle_timeout * connection_manager.raiden.chain.estimate_blocktime() * 10 ) assert timeout > 0 exception = ValueError('timeout while waiting for leave') with gevent.Timeout(timeout, exception=exception): RaidenAPI(raiden_network[0].raiden).token_network_leave( registry_address, token_address, ) before_block = connection_manager.raiden.chain.block_number() wait_blocks = sender_channel.settle_timeout + 10 # wait until both chains are synced? wait_until_block( connection_manager.raiden.chain, before_block + wait_blocks, ) wait_until_block( receiver.chain, before_block + wait_blocks, ) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert receiver_channel[0].settle_transaction is not None
def test_participant_selection(raiden_network, token_addresses): # pylint: disable=too-many-locals registry_address = raiden_network[0].raiden.default_registry.address one_to_n_address = raiden_network[0].raiden.default_one_to_n_address token_address = token_addresses[0] # connect the first node - this will register the token and open the first channel # Since there is no other nodes available to connect to this call will do nothing more RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=TokenAmount(100)) # Test invalid argument values with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=TokenAmount(-1)) with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=TokenAmount(100), joinable_funds_target=2, ) with pytest.raises(InvalidAmount): RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address=registry_address, token_address=token_address, funds=TokenAmount(100), joinable_funds_target=-1, ) # Call the connect endpoint for all but the first node connect_greenlets = [ gevent.spawn( RaidenAPI(app.raiden).token_network_connect, registry_address, token_address, 100) for app in raiden_network[1:] ] gevent.wait(connect_greenlets) token_network_registry_address = views.get_token_network_address_by_token_address( views.state_from_raiden(raiden_network[0].raiden), token_network_registry_address=registry_address, token_address=token_address, ) connection_managers = [ app.raiden.connection_manager_for_token_network( token_network_registry_address) for app in raiden_network ] unsaturated_connection_managers = connection_managers[:] exception = AssertionError("Unsaturated connection managers", unsaturated_connection_managers) with gevent.Timeout(120, exception): while unsaturated_connection_managers: for manager in unsaturated_connection_managers: if is_manager_saturated(manager, registry_address, token_address): unsaturated_connection_managers.remove(manager) gevent.sleep(1) assert saturated_count(connection_managers, registry_address, token_address) == len(connection_managers) # ensure unpartitioned network for app in raiden_network: node_state = views.state_from_raiden(app.raiden) network_state = views.get_token_network_by_token_address( node_state, registry_address, token_address) assert network_state is not None for target in raiden_network: if target.raiden.address == app.raiden.address: continue _, routes, _ = routing.get_best_routes( chain_state=node_state, token_network_address=network_state.address, one_to_n_address=one_to_n_address, from_address=app.raiden.address, to_address=target.raiden.address, amount=PaymentAmount(1), previous_address=None, pfs_config=None, privkey=b"", # not used if pfs is not configured ) assert routes is not None # create a transfer to the leaving node, so we have a channel to settle for app in raiden_network: sender = app.raiden sender_channel = next( (channel_state for channel_state in RaidenAPI( sender).get_channel_list(registry_address=registry_address, token_address=token_address) if channel_state.our_state.contract_balance > 0 and channel_state.partner_state.contract_balance > 0), None, ) # choose a fully funded channel from sender if sender_channel: break assert sender_channel registry_address = sender.default_registry.address receiver = next( app.raiden for app in raiden_network if app.raiden.address == sender_channel.partner_state.address) # assert there is a direct channel receiver -> sender (vv) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert len(receiver_channel) == 1 with gevent.Timeout(30, exception=ValueError("partner not reachable")): waiting.wait_for_healthy(sender, receiver.address, PaymentAmount(1)) with watch_for_unlock_failures(*raiden_network): amount = PaymentAmount(1) RaidenAPI(sender).transfer_and_wait(registry_address, token_address, amount, receiver.address, transfer_timeout=10) with gevent.Timeout( 30, exception=ValueError( "timeout while waiting for incoming transaction")): wait_for_transaction(receiver, registry_address, token_address, sender.address) # test `leave()` method connection_manager = connection_managers[0] timeout = (sender_channel.settle_timeout * estimate_blocktime(connection_manager.raiden.rpc_client) * 10) assert timeout > 0 channels = views.list_channelstate_for_tokennetwork( chain_state=views.state_from_raiden(connection_manager.raiden), token_network_registry_address=registry_address, token_address=token_address, ) channel_identifiers = [channel.identifier for channel in channels] with gevent.Timeout( timeout, exception=ValueError("timeout while waiting for leave")): # sender leaves the network RaidenAPI(sender).token_network_leave(registry_address, token_address) with gevent.Timeout(timeout, exception=ValueError( f"Channels didnt get settled after {timeout}")): waiting.wait_for_settle( raiden=connection_manager.raiden, token_network_registry_address=registry_address, token_address=token_address, channel_ids=channel_identifiers, retry_timeout=0.1, )
def run_test_send_queued_messages( raiden_network, deposit, token_addresses, network_wait, ): app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) with dont_handle_node_change_network_state(): # stop app1 - transfer must be left unconfirmed app1.stop() # make a few transfers from app0 to app1 amount = 1 spent_amount = 7 identifier = 1 for _ in range(spent_amount): app0.raiden.mediated_transfer_async( token_network_identifier=token_network_identifier, amount=amount, target=app1.raiden.address, identifier=identifier, ) identifier += 1 # restart app0 app0.raiden.stop() new_transport = MatrixTransport( app0.raiden.config['transport']['matrix'], ) 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_secret_registry=app0.raiden.default_secret_registry, default_service_registry=app0.raiden.default_service_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app1.start() app0_restart.start() waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) exception = RuntimeError('Timeout while waiting for new channel') with gevent.Timeout(5, exception=exception): waiting.wait_for_newchannel( raiden=app0_restart.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app1.raiden.address, retry_timeout=network_wait, ) exception = RuntimeError( 'Timeout while waiting for balance update for app0') with gevent.Timeout(30, exception=exception): waiting.wait_for_payment_balance( raiden=app0_restart.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app1.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) waiting.wait_for_payment_balance( raiden=app1.raiden, payment_network_id=payment_network_id, token_address=token_address, partner_address=app0_restart.raiden.address, target_address=app1.raiden.address, target_balance=spent_amount, retry_timeout=network_wait, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], )
def test_participant_selection(raiden_network, token_addresses, skip_if_tester): registry_address = raiden_network[0].raiden.default_registry.address # pylint: disable=too-many-locals token_address = token_addresses[0] # connect the first node (will register the token if necessary) RaidenAPI(raiden_network[0].raiden).token_network_connect( registry_address, token_address, 100, ) # connect the other nodes connect_greenlets = [ gevent.spawn( RaidenAPI(app.raiden).token_network_connect, registry_address, token_address, 100, ) for app in raiden_network[1:] ] gevent.wait(connect_greenlets) token_network_registry_address = views.get_token_network_identifier_by_token_address( views.state_from_raiden(raiden_network[0].raiden), payment_network_id=registry_address, token_address=token_address, ) connection_managers = [ app.raiden.connection_manager_for_token_network( token_network_registry_address, ) for app in raiden_network ] unsaturated_connection_managers = connection_managers[:] with gevent.Timeout( 120, AssertionError('Unsaturated connection managers', unsaturated_connection_managers), ): while unsaturated_connection_managers: for manager in unsaturated_connection_managers: if is_manager_saturated(manager, registry_address, token_address): unsaturated_connection_managers.remove(manager) gevent.sleep(1) assert saturated_count( connection_managers, registry_address, token_address, ) == len(connection_managers) # ensure unpartitioned network for app in raiden_network: node_state = views.state_from_raiden(app.raiden) network_state = views.get_token_network_by_token_address( node_state, registry_address, token_address, ) assert network_state is not None for target in raiden_network: if target.raiden.address == app.raiden.address: continue routes = routing.get_best_routes( node_state, network_state.address, app.raiden.address, target.raiden.address, 1, None, ) assert routes is not None # create a transfer to the leaving node, so we have a channel to settle sender = raiden_network[-1].raiden receiver = raiden_network[0].raiden registry_address = sender.default_registry.address # assert there is a direct channel receiver -> sender (vv) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert len(receiver_channel) == 1 receiver_channel = receiver_channel[0] # assert there is a direct channel sender -> receiver sender_channel = RaidenAPI(sender).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=receiver.address, ) assert len(sender_channel) == 1 sender_channel = sender_channel[0] exception = ValueError('partner not reachable') with gevent.Timeout(30, exception=exception): waiting.wait_for_healthy(sender, receiver.address, 1) amount = 1 RaidenAPI(sender).transfer_and_wait( registry_address, token_address, amount, receiver.address, transfer_timeout=10, ) exception = ValueError('timeout while waiting for incoming transaction') with gevent.Timeout(30, exception=exception): wait_for_transaction( receiver, registry_address, token_address, sender.address, ) # test `leave()` method connection_manager = connection_managers[0] timeout = ( sender_channel.settle_timeout * connection_manager.raiden.chain.estimate_blocktime() * 10 ) assert timeout > 0 exception = ValueError('timeout while waiting for leave') with gevent.Timeout(timeout, exception=exception): RaidenAPI(raiden_network[0].raiden).token_network_leave( registry_address, token_address, ) before_block = connection_manager.raiden.chain.block_number() wait_blocks = sender_channel.settle_timeout + 10 # wait until both chains are synced? wait_until_block( connection_manager.raiden.chain, before_block + wait_blocks, ) wait_until_block( receiver.chain, before_block + wait_blocks, ) receiver_channel = RaidenAPI(receiver).get_channel_list( registry_address=registry_address, token_address=token_address, partner_address=sender.address, ) assert receiver_channel[0].settle_transaction is not None