def test_get_connection_managers_info(api_server_test_instance: APIServer, token_addresses): # check that there are no registered tokens request = grequests.get( api_url_for(api_server_test_instance, "connectionsinforesource")) response = request.send().response result = get_json_response(response) assert len(result) == 0 funds = 100 token_address1 = to_checksum_address(token_addresses[0]) connect_data_obj = {"funds": funds} request = grequests.put( api_url_for(api_server_test_instance, "connectionsresource", token_address=token_address1), json=connect_data_obj, ) response = request.send().response assert_no_content_response(response) # check that there now is one registered channel manager request = grequests.get( api_url_for(api_server_test_instance, "connectionsinforesource")) response = request.send().response result = get_json_response(response) assert isinstance(result, dict) and len(result.keys()) == 1 assert token_address1 in result assert isinstance(result[token_address1], dict) assert set(result[token_address1].keys()) == { "funds", "sum_deposits", "channels" }
def test_get_connections_info( raiden_network: List[RaidenService], api_server_test_instance: APIServer, token_addresses: List[TokenAddress], ): token_address = token_addresses[0] # Check that there are no registered tokens request = grequests.get( api_url_for(api_server_test_instance, "connectionsinforesource")) response = request.send().response result = get_json_response(response) assert len(result) == 0 # Create a channel app0 = raiden_network[0] RaidenAPI(app0).channel_open( registry_address=app0.default_registry.address, token_address=token_address, partner_address=factories.make_address(), ) # Check that there is a channel for one token, now cs_token_address = to_checksum_address(token_address) request = grequests.get( api_url_for(api_server_test_instance, "connectionsinforesource")) response = request.send().response result = get_json_response(response) assert isinstance(result, dict) and len(result.keys()) == 1 assert cs_token_address in result assert isinstance(result[cs_token_address], dict) assert set(result[cs_token_address].keys()) == {"sum_deposits", "channels"}
def test_get_token_network_for_token( api_server_test_instance, token_amount, token_addresses, raiden_network: List[RaidenService], contract_manager, retry_timeout, unregistered_token, ): app0 = raiden_network[0] new_token_address = unregistered_token # Wait until Raiden can start using the token contract. # Here, the block at which the contract was deployed should be confirmed by Raiden. # Therefore, until that block is received. wait_for_block( raiden=app0, block_number=BlockNumber(app0.get_block_number() + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS + 1), retry_timeout=retry_timeout, ) # unregistered token returns 404 token_request = grequests.get( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(new_token_address), )) token_response = token_request.send().response assert_proper_response(token_response, status_code=HTTPStatus.NOT_FOUND) # register token register_request = grequests.put( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(new_token_address), )) register_response = register_request.send().response assert_proper_response(register_response, status_code=HTTPStatus.CREATED) token_network_address = get_json_response( register_response)["token_network_address"] wait_for_token_network(app0, app0.default_registry.address, new_token_address, 0.1) # now it should return the token address token_request = grequests.get( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(new_token_address), )) token_response = token_request.send().response assert_proper_response(token_response, status_code=HTTPStatus.OK) assert token_network_address == get_json_response(token_response)
def test_channel_events(api_server_test_instance: APIServer, token_addresses): # let's create a new channel partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, status_code=HTTPStatus.CREATED) request = grequests.get( api_url_for( api_server_test_instance, "tokenchanneleventsresourceblockchain", token_address=token_address, from_block=str(GENESIS_BLOCK_NUMBER), )) response = request.send().response assert_proper_response(response, status_code=HTTPStatus.OK) assert len(get_json_response(response)) > 0
def test_api_channel_close_insufficient_eth( api_server_test_instance: APIServer, token_addresses, reveal_timeout): # let's create a new channel partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response balance = 0 assert_proper_response(response, status_code=HTTPStatus.CREATED) channel_identifier = 1 json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": str(balance), "state": ChannelState.STATE_OPENED.value, "reveal_timeout": str(reveal_timeout), "channel_identifier": str(channel_identifier), "total_deposit": "0", }) assert check_dict_nested_attrs(json_response, expected_response) # let's burn all eth and try to close the channel burn_eth(api_server_test_instance.rest_api.raiden_api.raiden.rpc_client) request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=partner_address, ), json={"state": ChannelState.STATE_CLOSED.value}, ) response = request.send().response assert_proper_response(response, HTTPStatus.PAYMENT_REQUIRED) json_response = get_json_response(response) assert "insufficient ETH" in json_response["errors"]
def test_api_get_raiden_version(api_server_test_instance: APIServer): request = grequests.get( api_url_for(api_server_test_instance, "versionresource")) response = request.send().response assert_proper_response(response) raiden_version = get_system_spec()["raiden"] assert get_json_response(response) == {"version": raiden_version}
def test_api_query_our_address(api_server_test_instance: APIServer): request = grequests.get( api_url_for(api_server_test_instance, "addressresource")) response = request.send().response assert_proper_response(response) our_address = api_server_test_instance.rest_api.raiden_api.address assert get_json_response(response) == { "our_address": to_checksum_address(our_address) }
def test_api_get_node_settings(api_server_test_instance: APIServer): request = grequests.get( api_url_for(api_server_test_instance, "nodesettingsresource")) response = request.send().response assert_proper_response(response) pfs_config = api_server_test_instance.rest_api.raiden_api.raiden.config.pfs_config assert get_json_response(response) == { "pathfinding_service_address": pfs_config and pfs_config.info.url }
def test_api_get_channel_list(api_server_test_instance: APIServer, token_addresses, reveal_timeout): partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" request = grequests.get( api_url_for(api_server_test_instance, "channelsresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert json_response == [] # let's create a new channel token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) request = grequests.get( api_url_for(api_server_test_instance, "channelsresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) channel_info = json_response[0] assert channel_info["partner_address"] == partner_address assert channel_info["token_address"] == to_checksum_address(token_address) assert channel_info["total_deposit"] == "0" assert "token_network_address" in channel_info
def test_api_channel_status_channel_nonexistant( api_server_test_instance: APIServer, token_addresses): partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] request = grequests.get( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=partner_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.NOT_FOUND) assert get_json_response(response)["errors"] == ( "Channel with partner '{}' for token '{}' could not be found.".format( to_checksum_address(partner_address), to_checksum_address(token_address)))
def test_connect_insufficient_reserve(api_server_test_instance: APIServer, token_addresses): # Burn all eth and then try to connect to a token network burn_eth(api_server_test_instance.rest_api.raiden_api.raiden.rpc_client) funds = 100 token_address1 = to_checksum_address(token_addresses[0]) connect_data_obj = {"funds": funds} request = grequests.put( api_url_for(api_server_test_instance, "connectionsresource", token_address=token_address1), json=connect_data_obj, ) response = request.send().response assert_proper_response(response, HTTPStatus.PAYMENT_REQUIRED) json_response = get_json_response(response) assert "The account balance is below the estimated amount" in json_response[ "errors"]
def test_api_get_contract_infos(api_server_test_instance: APIServer): request = grequests.get( api_url_for(api_server_test_instance, "contractsresource")) response = request.send().response assert_proper_response(response) json = get_json_response(response) assert json["contracts_version"] == CONTRACTS_VERSION for contract_name in [ "token_network_registry_address", "secret_registry_address", "service_registry_address", "user_deposit_address", "monitoring_service_address", "one_to_n_address", ]: address = json[contract_name] if address is not None: assert is_checksum_address(address)
def test_api_tokens(api_server_test_instance: APIServer, blockchain_services, token_addresses): partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address1 = token_addresses[0] token_address2 = token_addresses[1] settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address1), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address2), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) # and now let's get the token list request = grequests.get( api_url_for(api_server_test_instance, "tokensresource")) response = request.send().response assert_proper_response(response) json_response = get_json_response(response) expected_response = [ to_checksum_address(token_address1), to_checksum_address(token_address2) ] assert set(json_response) == set(expected_response)
def test_api_payments_with_secret_and_hash(api_server_test_instance: APIServer, raiden_network, token_addresses): _, app1 = raiden_network amount = 100 identifier = 42 token_address = token_addresses[0] target_address = app1.raiden.address secret = to_hex(factories.make_secret()) secret_hash = to_hex(sha256(to_bytes(hexstr=secret)).digest()) our_address = api_server_test_instance.rest_api.raiden_api.address payment = { "initiator_address": to_checksum_address(our_address), "target_address": to_checksum_address(target_address), "token_address": to_checksum_address(token_address), "amount": str(amount), "identifier": str(identifier), } request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ), json={ "amount": str(amount), "identifier": str(identifier), "secret": secret, "secret_hash": secret_hash, }, ) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response) json_response = get_json_response(response) assert_payment_secret_and_hash(json_response, payment) assert secret == json_response["secret"] assert secret_hash == json_response["secret_hash"]
def test_api_payments_with_secret_and_hash(api_server_test_instance: APIServer, raiden_network: List[RaidenService], token_addresses): _, app1 = raiden_network token_address = token_addresses[0] target_address = app1.address secret, secret_hash = factories.make_secret_with_hash() our_address = api_server_test_instance.rest_api.raiden_api.address payment = { "initiator_address": to_checksum_address(our_address), "target_address": to_checksum_address(target_address), "token_address": to_checksum_address(token_address), "amount": DEFAULT_AMOUNT, "identifier": DEFAULT_ID, } request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ), json={ "amount": DEFAULT_AMOUNT, "identifier": DEFAULT_ID, "secret": to_hex(secret), "secret_hash": to_hex(secret_hash), }, ) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response) json_response = get_json_response(response) assert_payment_secret_and_hash(json_response, payment) assert to_hex(secret) == json_response["secret"] assert to_hex(secret_hash) == json_response["secret_hash"]
def test_api_timestamp_format(api_server_test_instance: APIServer, raiden_network: List[RaidenService], token_addresses) -> None: _, app1 = raiden_network amount = 200 identifier = 42 token_address = token_addresses[0] target_address = app1.address payment_url = api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ) # Make payment grequests.post(payment_url, json={ "amount": str(amount), "identifier": str(identifier) }).send() json_response = get_json_response( grequests.get(payment_url).send().response) assert len(json_response) == 1, "payment response had no event record" event_data = json_response[0] assert "log_time" in event_data, "missing log_time attribute from event record" log_timestamp = event_data["log_time"] # python (and javascript) can parse strings with either space or T as a separator of date # and time and still treat it as a ISO8601 string log_date = datetime.datetime.fromisoformat(log_timestamp) log_timestamp_iso = log_date.isoformat() assert log_timestamp_iso == log_timestamp, "log_time is not a valid ISO8601 string"
def test_query_partners_by_token(api_server_test_instance: APIServer, blockchain_services, token_addresses): first_partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" second_partner_address = "0x29FA6cf0Cce24582a9B20DB94Be4B6E017896038" token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": first_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) json_response = get_json_response(response) channel_data_obj["partner_address"] = second_partner_address request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) json_response = get_json_response(response) # and a channel for another token channel_data_obj[ "partner_address"] = "0xb07937AbA15304FBBB0Bf6454a9377a76E3dD39E" channel_data_obj["token_address"] = to_checksum_address(token_address) request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) # and now let's query our partners per token for the first token request = grequests.get( api_url_for( api_server_test_instance, "partnersresourcebytokenaddress", token_address=to_checksum_address(token_address), )) response = request.send().response assert_proper_response(response) json_response = get_json_response(response) expected_response = [ { "partner_address": first_partner_address, "channel": "/api/v1/channels/{}/{}".format( to_checksum_address(token_address), to_checksum_address(first_partner_address)), }, { "partner_address": second_partner_address, "channel": "/api/v1/channels/{}/{}".format( to_checksum_address(token_address), to_checksum_address(second_partner_address)), }, ] assert all(r in json_response for r in expected_response)
def test_register_token( api_server_test_instance, token_amount, raiden_network: List[RaidenService], contract_manager, retry_timeout, ): app0 = raiden_network[0] contract_proxy, _ = app0.rpc_client.deploy_single_contract( contract_name=CONTRACT_HUMAN_STANDARD_TOKEN, contract=contract_manager.get_contract(CONTRACT_HUMAN_STANDARD_TOKEN), constructor_parameters=(token_amount, 2, "raiden", "Rd1"), ) new_token_address = Address(to_canonical_address(contract_proxy.address)) contract_proxy, _ = app0.rpc_client.deploy_single_contract( contract_name=CONTRACT_HUMAN_STANDARD_TOKEN, contract=contract_manager.get_contract(CONTRACT_HUMAN_STANDARD_TOKEN), constructor_parameters=(token_amount, 2, "raiden", "Rd2"), ) other_token_address = Address(to_canonical_address(contract_proxy.address)) # Wait until Raiden can start using the token contract. # Here, the block at which the contract was deployed should be confirmed by Raiden. # Therefore, until that block is received. wait_for_block( raiden=app0, block_number=BlockNumber(app0.get_block_number() + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS + 1), retry_timeout=retry_timeout, ) wait_for_block( raiden=app0, block_number=BlockNumber(app0.get_block_number() + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS + 1), retry_timeout=retry_timeout, ) register_request = grequests.put( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(new_token_address), )) register_response = register_request.send().response assert_proper_response(register_response, status_code=HTTPStatus.CREATED) response_json = get_json_response(register_response) assert "token_network_address" in response_json assert is_checksum_address(response_json["token_network_address"]) # now try to reregister it and get the error conflict_request = grequests.put( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(new_token_address), )) conflict_response = conflict_request.send().response assert_response_with_error(conflict_response, HTTPStatus.CONFLICT) # Test that adding a second token throws a forbidden error forbidden_request = grequests.put( api_url_for( api_server_test_instance, "registertokenresource", token_address=to_checksum_address(other_token_address), )) forbidden_response = forbidden_request.send().response assert_response_with_error(forbidden_response, HTTPStatus.FORBIDDEN) response_json = get_json_response(forbidden_response) assert "Number of token networks will exceed the maximum of" in response_json[ "errors"]
def test_api_payments(api_server_test_instance: APIServer, raiden_network, token_addresses, deposit): _, app1 = raiden_network amount = 100 identifier = 42 token_address = token_addresses[0] target_address = app1.raiden.address our_address = api_server_test_instance.rest_api.raiden_api.address payment = { "initiator_address": to_checksum_address(our_address), "target_address": to_checksum_address(target_address), "token_address": to_checksum_address(token_address), "amount": str(amount), "identifier": str(identifier), } # Test a normal payment request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ), json={ "amount": str(amount), "identifier": str(identifier) }, ) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response) json_response = get_json_response(response) assert_payment_secret_and_hash(json_response, payment) # Test a payment without providing an identifier payment["amount"] = "1" request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ), json={"amount": "1"}, ) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response) json_response = get_json_response(response) assert_payment_secret_and_hash(json_response, payment) # Test that trying out a payment with an amount higher than what is available returns an error payment["amount"] = str(deposit) request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target_address), ), json={"amount": str(deposit)}, ) response = request.send().response assert_proper_response(response, status_code=HTTPStatus.CONFLICT) # Test that querying the internal events resource works limit = 5 request = grequests.get( api_url_for(api_server_test_instance, "raideninternaleventsresource", limit=limit, offset=0)) response = request.send().response assert_proper_response(response) events = response.json() assert len(events) == limit assert all("TimestampedEvent" in event for event in events)
def test_api_channel_deposit_limit( api_server_test_instance, proxy_manager, token_network_registry_address, token_addresses, reveal_timeout, ): token_address = token_addresses[0] registry = proxy_manager.token_network_registry( token_network_registry_address, BLOCK_ID_LATEST) token_network_address = registry.get_token_network(token_address, BLOCK_ID_LATEST) token_network = proxy_manager.token_network(token_network_address, BLOCK_ID_LATEST) deposit_limit = token_network.channel_participant_deposit_limit( BLOCK_ID_LATEST) # let's create a new channel and deposit exactly the limit amount first_partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" settle_timeout = 1650 channel_data_obj = { "partner_address": first_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "total_deposit": str(deposit_limit), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) first_channel_identifier = 1 json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": str(deposit_limit), "state": ChannelState.STATE_OPENED.value, "channel_identifier": str(first_channel_identifier), "total_deposit": str(deposit_limit), }) assert check_dict_nested_attrs(json_response, expected_response) # now let's open a channel and deposit a bit more than the limit second_partner_address = "0x29FA6cf0Cce24582a9B20DB94Be4B6E017896038" balance_failing = deposit_limit + 1 # token has two digits channel_data_obj = { "partner_address": second_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "total_deposit": str(balance_failing), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT) json_response = get_json_response(response) assert ( json_response["errors"] == "Deposit of 75000000000000001 is larger than the channel participant deposit limit" )
def test_api_channel_open_close_and_settle(api_server_test_instance: APIServer, token_addresses, reveal_timeout): # let's create a new channel partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response balance = 0 assert_proper_response(response, status_code=HTTPStatus.CREATED) channel_identifier = 1 json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": str(balance), "state": ChannelState.STATE_OPENED.value, "reveal_timeout": str(reveal_timeout), "channel_identifier": str(channel_identifier), "total_deposit": "0", }) assert check_dict_nested_attrs(json_response, expected_response) token_network_address = json_response["token_network_address"] # let's close the channel request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=partner_address, ), json={"state": ChannelState.STATE_CLOSED.value}, ) response = request.send().response assert_proper_response(response) expected_response = { "token_network_address": token_network_address, "channel_identifier": str(channel_identifier), "partner_address": partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "state": ChannelState.STATE_CLOSED.value, "balance": str(balance), "total_deposit": str(balance), } assert check_dict_nested_attrs(get_json_response(response), expected_response) # try closing the channel again request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=partner_address, ), json={"state": ChannelState.STATE_CLOSED.value}, ) # Closing the channel again should not work response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT) # Try sending a payment when channel is closed request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(partner_address), ), json={"amount": "1"}, ) # Payment should not work since channel is closing response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT) # Try to create channel with the same partner again before previous channnel settles request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) # Channel exists and is currently being settled so API request to open channel should fail response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT)
def test_payment_events_endpoints(api_server_test_instance: APIServer, raiden_network, token_addresses): app0, app1, app2 = raiden_network amount1 = PaymentAmount(10) identifier1 = PaymentID(42) secret1, secrethash1 = factories.make_secret_with_hash() token_address = token_addresses[0] app0_address = app0.raiden.address target1_address = app1.raiden.address target2_address = app2.raiden.address app1_server = prepare_api_server(app1) app2_server = prepare_api_server(app2) # app0 is sending tokens to target 1 request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target1_address), ), json={ "amount": str(amount1), "identifier": str(identifier1), "secret": to_hex(secret1) }, ) request.send() # app0 is sending some tokens to target 2 identifier2 = PaymentID(43) amount2 = PaymentAmount(10) secret2, secrethash2 = factories.make_secret_with_hash() request = grequests.post( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target2_address), ), json={ "amount": str(amount2), "identifier": str(identifier2), "secret": to_hex(secret2) }, ) request.send() # target1 also sends some tokens to target 2 identifier3 = PaymentID(44) amount3 = PaymentAmount(5) secret3, secrethash3 = factories.make_secret_with_hash() request = grequests.post( api_url_for( app1_server, "token_target_paymentresource", token_address=to_checksum_address(token_address), target_address=to_checksum_address(target2_address), ), json={ "amount": str(amount3), "identifier": str(identifier3), "secret": to_hex(secret3) }, ) request.send() timeout = block_offset_timeout( app2.raiden, "Waiting for transfer received success in the WAL timed out") with watch_for_unlock_failures(*raiden_network), timeout: result = wait_for_received_transfer_result( app1.raiden, identifier1, amount1, app1.raiden.alarm.sleep_time, secrethash1) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg result = wait_for_received_transfer_result( app2.raiden, identifier2, amount2, app2.raiden.alarm.sleep_time, secrethash2) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg result = wait_for_received_transfer_result( app2.raiden, identifier3, amount3, app2.raiden.alarm.sleep_time, secrethash3) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg # test endpoint without (partner and token) for sender request = grequests.get( api_url_for(api_server_test_instance, "paymentresource")) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier1), "target": to_checksum_address(target1_address), "token_address": to_checksum_address(token_address), }, ) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier2), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) # test endpoint without (partner and token) for target1 request = grequests.get(api_url_for(app1_server, "paymentresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "token_address": to_checksum_address(token_address), }, ) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier3), "token_address": to_checksum_address(token_address), }, ) # test endpoint without (partner and token) for target2 request = grequests.get(api_url_for(app2_server, "paymentresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier2), "token_address": to_checksum_address(token_address), }, ) assert must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier3), "token_address": to_checksum_address(token_address), }, ) # test endpoint without partner for app0 request = grequests.get( api_url_for(api_server_test_instance, "token_paymentresource", token_address=token_address)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier1), "target": to_checksum_address(target1_address), "token_address": to_checksum_address(token_address), }, ) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier2), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) # test endpoint without partner for app0 but with limit/offset to get only first request = grequests.get( api_url_for( api_server_test_instance, "token_paymentresource", token_address=token_address, limit=1, offset=0, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier1), "target": to_checksum_address(target1_address), "token_address": to_checksum_address(token_address), }, ) assert len(json_response) == 1 # test endpoint without partner for app0 but with limit/offset to get only second request = grequests.get( api_url_for( api_server_test_instance, "token_paymentresource", token_address=token_address, limit=1, offset=1, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier2), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) # test endpoint without partner for target1 request = grequests.get( api_url_for(app1_server, "token_paymentresource", token_address=token_address)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "token_address": to_checksum_address(token_address), }, { "event": "EventPaymentSentSuccess", "identifier": str(identifier3), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) # test endpoint without partner for target2 request = grequests.get( api_url_for(app2_server, "token_paymentresource", token_address=token_address)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier2), "token_address": to_checksum_address(token_address), }, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier3), "token_address": to_checksum_address(token_address), }, ) # test endpoint for token and partner for app0 request = grequests.get( api_url_for( api_server_test_instance, "token_target_paymentresource", token_address=token_address, target_address=target1_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier1), "target": to_checksum_address(target1_address), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier2), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) # test endpoint for token and partner for target1. Check both partners # to see that filtering works correctly request = grequests.get( api_url_for( app1_server, "token_target_paymentresource", token_address=token_address, target_address=target2_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event( json_response, { "event": "EventPaymentSentSuccess", "identifier": str(identifier3), "target": to_checksum_address(target2_address), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "token_address": to_checksum_address(token_address), }, ) request = grequests.get( api_url_for( app1_server, "token_target_paymentresource", token_address=token_address, target_address=target1_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 0 # test endpoint for token and partner for target2 request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=token_address, target_address=app0_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier2), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier3), "token_address": to_checksum_address(token_address), }, ) request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=token_address, target_address=target1_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier3), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier2), "token_address": to_checksum_address(token_address), }, ) assert not must_have_event( json_response, { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "token_address": to_checksum_address(token_address), }, ) # also add a test for filtering by wrong token address request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=target1_address, target_address=target1_address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 0 app1_server.stop() app2_server.stop()
def test_api_channel_open_and_deposit(api_server_test_instance: APIServer, token_addresses, reveal_timeout): first_partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] token_address_hex = to_checksum_address(token_address) settle_timeout = 1650 channel_data_obj = { "partner_address": first_partner_address, "token_address": token_address_hex, "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), } # First let's try to create channel with the null address and see error is handled channel_data_obj["partner_address"] = NULL_ADDRESS_HEX request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_response_with_error(response, status_code=HTTPStatus.BAD_REQUEST) # now let's really create a new channel channel_data_obj["partner_address"] = first_partner_address request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) first_channel_id = 1 json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": "0", "state": ChannelState.STATE_OPENED.value, "channel_identifier": "1", "total_deposit": "0", }) assert check_dict_nested_attrs(json_response, expected_response) token_network_address = json_response["token_network_address"] # Now let's try to open the same channel again, because it is possible for # the participants to race on the channel creation, this is not considered # an error. request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert check_dict_nested_attrs(json_response, expected_response) # now let's open a channel and make a deposit too second_partner_address = "0x29FA6cf0Cce24582a9B20DB94Be4B6E017896038" total_deposit = 100 channel_data_obj = { "partner_address": second_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "total_deposit": str(total_deposit), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) second_channel_id = 2 json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": str(total_deposit), "state": ChannelState.STATE_OPENED.value, "channel_identifier": str(second_channel_id), "token_network_address": token_network_address, "total_deposit": str(total_deposit), }) assert check_dict_nested_attrs(json_response, expected_response) # assert depositing again with less than the initial deposit returns 409 request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=second_partner_address, ), json={"total_deposit": "99"}, ) response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT) # assert depositing negative amount fails request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=first_partner_address, ), json={"total_deposit": "-1000"}, ) response = request.send().response assert_proper_response(response, HTTPStatus.CONFLICT) # let's deposit on the first channel request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=first_partner_address, ), json={"total_deposit": str(total_deposit)}, ) response = request.send().response assert_proper_response(response) json_response = get_json_response(response) expected_response = { "channel_identifier": str(first_channel_id), "partner_address": first_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "state": ChannelState.STATE_OPENED.value, "balance": str(total_deposit), "total_deposit": str(total_deposit), "token_network_address": token_network_address, } assert check_dict_nested_attrs(json_response, expected_response) # let's try querying for the second channel request = grequests.get( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=second_partner_address, )) response = request.send().response assert_proper_response(response) json_response = get_json_response(response) expected_response = { "channel_identifier": str(second_channel_id), "partner_address": second_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), "state": ChannelState.STATE_OPENED.value, "balance": str(total_deposit), "total_deposit": str(total_deposit), "token_network_address": token_network_address, } assert check_dict_nested_attrs(json_response, expected_response) # finally let's burn all eth and try to open another channel burn_eth(api_server_test_instance.rest_api.raiden_api.raiden.rpc_client) channel_data_obj = { "partner_address": "0xf3AF96F89b3d7CdcBE0C083690A28185Feb0b3CE", "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.PAYMENT_REQUIRED) json_response = get_json_response(response) assert "The account balance is below the estimated amount" in json_response[ "errors"]
def test_payment_events_endpoints(api_server_test_instance: APIServer, raiden_network: List[RaidenService], token_addresses): app0, app1, app2 = raiden_network token_address0 = token_addresses[0] token_address1 = token_addresses[1] app0_server = api_server_test_instance app1_server = prepare_api_server(app1) app2_server = prepare_api_server(app2) # Payment 1: app0 is sending tokens of token0 to app1 identifier1 = PaymentID(10) amount1 = PaymentAmount(10) secret1, secrethash1 = factories.make_secret_with_hash() request = grequests.post( api_url_for( app0_server, "token_target_paymentresource", token_address=to_checksum_address(token_address0), target_address=to_checksum_address(app1.address), ), json={ "amount": str(amount1), "identifier": str(identifier1), "secret": to_hex(secret1) }, ) request.send() # Payment 2: app0 is sending some tokens of token1 to app2 identifier2 = PaymentID(20) amount2 = PaymentAmount(10) secret2, secrethash2 = factories.make_secret_with_hash() request = grequests.post( api_url_for( app0_server, "token_target_paymentresource", token_address=to_checksum_address(token_address1), target_address=to_checksum_address(app2.address), ), json={ "amount": str(amount2), "identifier": str(identifier2), "secret": to_hex(secret2) }, ) request.send() # Payment 3: app0 is sending some tokens of token0 to app2 identifier3 = PaymentID(30) amount3 = PaymentAmount(17) secret3, secrethash3 = factories.make_secret_with_hash() request = grequests.post( api_url_for( app0_server, "token_target_paymentresource", token_address=to_checksum_address(token_address0), target_address=to_checksum_address(app1.address), ), json={ "amount": str(amount3), "identifier": str(identifier3), "secret": to_hex(secret3) }, ) request.send() timeout = block_offset_timeout( app2, "Waiting for transfer received success in the WAL timed out") with watch_for_unlock_failures(*raiden_network), timeout: result = wait_for_received_transfer_result(app1, identifier1, amount1, app1.alarm.sleep_time, secrethash1) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg result = wait_for_received_transfer_result(app2, identifier2, amount2, app2.alarm.sleep_time, secrethash2) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg result = wait_for_received_transfer_result(app1, identifier3, amount3, app1.alarm.sleep_time, secrethash3) msg = f"Unexpected transfer result: {str(result)}" assert result == TransferWaitResult.UNLOCKED, msg # predefine events for later use in assertions event_sent_1 = { "event": "EventPaymentSentSuccess", "identifier": str(identifier1), "target": to_checksum_address(app1.address), "token_address": to_checksum_address(token_address0), } event_sent_2 = { "event": "EventPaymentSentSuccess", "identifier": str(identifier2), "target": to_checksum_address(app2.address), "token_address": to_checksum_address(token_address1), } event_sent_3 = { "event": "EventPaymentSentSuccess", "identifier": str(identifier3), "target": to_checksum_address(app1.address), "token_address": to_checksum_address(token_address0), } event_received_1 = { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier1), "initiator": to_checksum_address(app0.address), "token_address": to_checksum_address(token_address0), } event_received_2 = { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier2), "initiator": to_checksum_address(app0.address), "token_address": to_checksum_address(token_address1), } event_received_3 = { "event": "EventPaymentReceivedSuccess", "identifier": str(identifier3), "initiator": to_checksum_address(app0.address), "token_address": to_checksum_address(token_address0), } # test app0 endpoint without (partner and token) for sender request = grequests.get(api_url_for(app0_server, "paymentresource")) with watch_for_unlock_failures(*raiden_network): response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event(json_response, event_sent_1) assert must_have_event(json_response, event_sent_2) assert must_have_event(json_response, event_sent_3) # test endpoint without (partner and token) for target1 request = grequests.get(api_url_for(app1_server, "paymentresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event(json_response, event_received_1) assert must_have_event(json_response, event_received_3) # test endpoint without (partner and token) for target2 request = grequests.get(api_url_for(app2_server, "paymentresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event(json_response, event_received_2) # test endpoint without partner for app0 request = grequests.get( api_url_for(app0_server, "token_paymentresource", token_address=token_address0)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event(json_response, event_sent_1) assert must_have_event(json_response, event_sent_3) # test endpoint without partner for app0 but with limit/offset to get only first request = grequests.get( api_url_for( app0_server, "token_paymentresource", token_address=token_address0, limit=1, offset=0, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_event(json_response, event_sent_1) assert len(json_response) == 1 # test endpoint without partner for app0 but with limit/offset # to get only second transfer of token_address request = grequests.get( api_url_for( app0_server, "token_paymentresource", token_address=token_address0, limit=1, offset=1, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) # this should return only payment 3, since payment 1 is offset # and payment 2 is of another token address assert len(json_response) == 1 assert must_have_event(json_response, event_sent_3) # test endpoint of app1 without partner for token_address request = grequests.get( api_url_for(app1_server, "token_paymentresource", token_address=token_address0)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events(json_response, event_received_1) assert must_have_events(json_response, event_received_3) # test endpoint of app2 without partner for token_address request = grequests.get( api_url_for(app2_server, "token_paymentresource", token_address=token_address0)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 0 # test endpoint of app2 without partner for token_address2 request = grequests.get( api_url_for(app2_server, "token_paymentresource", token_address=token_address1)) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert must_have_events(json_response, event_received_2) # test endpoint for token_address0 and partner for app0 request = grequests.get( api_url_for( app0_server, "token_target_paymentresource", token_address=token_address0, target_address=app1.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 2 assert must_have_event(json_response, event_sent_1) assert must_have_event(json_response, event_sent_3) request = grequests.get( api_url_for( app0_server, "token_target_paymentresource", token_address=token_address1, target_address=app2.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 1 assert must_have_event(json_response, event_sent_2) # test endpoint for token_address0 and partner for app1. Check both partners # to see that filtering works correctly request = grequests.get( api_url_for( app1_server, "token_target_paymentresource", token_address=token_address0, target_address=app2.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 0 request = grequests.get( api_url_for( app1_server, "token_target_paymentresource", token_address=token_address0, target_address=app0.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 2 assert must_have_event(json_response, event_received_1) assert must_have_event(json_response, event_received_3) # test app1 checking payments to himself request = grequests.get( api_url_for( app1_server, "token_target_paymentresource", token_address=token_address0, target_address=app1.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert len(json_response) == 0 # test endpoint for token and partner for app2 request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=token_address0, target_address=app0.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) # Since app2 has no payment with app0 in token_address assert len(json_response) == 0 # test endpoint for token2 and partner for app2 request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=token_address1, target_address=app0.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) # app2 has one payment with app0 in token_address2 assert len(json_response) == 1 assert must_have_events(json_response, event_received_2) request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=token_address0, target_address=app1.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) assert not must_have_event(json_response, event_received_2) # also add a test for filtering by wrong token address request = grequests.get( api_url_for( app2_server, "token_target_paymentresource", token_address=app1.address, target_address=app1.address, )) response = request.send().response assert_proper_response(response, HTTPStatus.BAD_REQUEST) app1_server.stop() app2_server.stop()
def test_api_channel_open_and_deposit_race( api_server_test_instance: APIServer, raiden_network, token_addresses, reveal_timeout, token_network_registry_address, retry_timeout, ): """Tests that a race for the same deposit from the API is handled properly The proxy's approve_and_set_total_deposit is raising a RaidenRecoverableError in case of races. That needs to be properly handled and not allowed to bubble out of the greenlet. Regression test for https://github.com/raiden-network/raiden/issues/4937 """ app0 = raiden_network[0] # let's create a new channel first_partner_address = "0x61C808D82A3Ac53231750daDc13c777b59310bD9" token_address = token_addresses[0] settle_timeout = 1650 channel_data_obj = { "partner_address": first_partner_address, "token_address": to_checksum_address(token_address), "settle_timeout": str(settle_timeout), "reveal_timeout": str(reveal_timeout), } request = grequests.put(api_url_for(api_server_test_instance, "channelsresource"), json=channel_data_obj) response = request.send().response assert_proper_response(response, HTTPStatus.CREATED) json_response = get_json_response(response) expected_response = channel_data_obj.copy() expected_response.update({ "balance": "0", "state": ChannelState.STATE_OPENED.value, "channel_identifier": "1", "total_deposit": "0", }) assert check_dict_nested_attrs(json_response, expected_response) # Prepare the deposit api call deposit_amount = TokenAmount(99) request = grequests.patch( api_url_for( api_server_test_instance, "channelsresourcebytokenandpartneraddress", token_address=token_address, partner_address=first_partner_address, ), json={"total_deposit": str(deposit_amount)}, ) # Spawn two greenlets doing the same deposit request greenlets = [gevent.spawn(request.send), gevent.spawn(request.send)] gevent.joinall(set(greenlets), raise_error=True) # Make sure that both responses are fine g1_response = greenlets[0].get().response assert_proper_response(g1_response, HTTPStatus.OK) json_response = get_json_response(g1_response) expected_response.update({ "total_deposit": str(deposit_amount), "balance": str(deposit_amount) }) assert check_dict_nested_attrs(json_response, expected_response) g2_response = greenlets[0].get().response assert_proper_response(g2_response, HTTPStatus.OK) json_response = get_json_response(g2_response) assert check_dict_nested_attrs(json_response, expected_response) # Wait for the deposit to be seen timeout_seconds = 20 exception = Exception( f"Expected deposit not seen within {timeout_seconds}") with gevent.Timeout(seconds=timeout_seconds, exception=exception): wait_for_participant_deposit( raiden=app0.raiden, token_network_registry_address=token_network_registry_address, token_address=token_address, partner_address=to_canonical_address(first_partner_address), target_address=app0.raiden.address, target_balance=deposit_amount, retry_timeout=retry_timeout, ) request = grequests.get( api_url_for(api_server_test_instance, "channelsresource")) response = request.send().response assert_proper_response(response, HTTPStatus.OK) json_response = get_json_response(response) channel_info = json_response[0] assert channel_info["token_address"] == to_checksum_address(token_address) assert channel_info["total_deposit"] == str(deposit_amount)