示例#1
0
def test_stress(
    raiden_network: List[App],
    restart_node: RestartNode,
    deposit: TokenAmount,
    retry_timeout: float,
    token_addresses: List[TokenAddress],
    port_generator: Iterator[Port],
) -> None:
    token_address = token_addresses[0]
    rest_apis = start_apiserver_for_network(raiden_network, port_generator)
    identifier_generator = count(start=1)

    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(raiden_network[0]),
        raiden_network[0].raiden.default_registry.address,
        token_address,
    )
    assert token_network_address

    for _ in range(2):
        assert_channels(raiden_network, token_network_address, deposit)

        with watch_for_unlock_failures(*raiden_network):
            stress_send_serial_transfers(rest_apis, token_address,
                                         identifier_generator, deposit)

        raiden_network, rest_apis = restart_network_and_apiservers(
            raiden_network, restart_node, rest_apis, port_generator,
            retry_timeout)

        assert_channels(raiden_network, token_network_address, deposit)

        with watch_for_unlock_failures(*raiden_network):
            stress_send_parallel_transfers(rest_apis, token_address,
                                           identifier_generator, deposit)

        raiden_network, rest_apis = restart_network_and_apiservers(
            raiden_network, restart_node, rest_apis, port_generator,
            retry_timeout)

        assert_channels(raiden_network, token_network_address, deposit)

        with watch_for_unlock_failures(*raiden_network):
            stress_send_and_receive_parallel_transfers(rest_apis,
                                                       token_address,
                                                       identifier_generator,
                                                       deposit)

        raiden_network, rest_apis = restart_network_and_apiservers(
            raiden_network, restart_node, rest_apis, port_generator,
            retry_timeout)

    restart_network(raiden_network, restart_node, retry_timeout)
示例#2
0
def test_regression_revealsecret_after_secret(
        raiden_network: List[App],
        token_addresses: List[TokenAddress]) -> None:
    """ A RevealSecret message received after a Unlock message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]
    identifier = PaymentID(1)
    token_network_registry_address = app0.raiden.default_registry.address
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(app0), token_network_registry_address, token)
    assert token_network_address, "The fixtures must register the token"

    payment_status = app0.raiden.mediated_transfer_async(
        token_network_address,
        amount=PaymentAmount(1),
        target=TargetAddress(app2.raiden.address),
        identifier=identifier,
    )
    with watch_for_unlock_failures(*raiden_network):
        assert payment_status.payment_done.wait()

    assert app1.raiden.wal, "The fixtures must start the app."
    event = raiden_events_search_for_item(app1.raiden, SendSecretReveal, {})
    assert event

    reveal_secret = RevealSecret(
        message_identifier=make_message_identifier(),
        secret=event.secret,
        signature=EMPTY_SIGNATURE,
    )
    app2.raiden.sign(reveal_secret)
    app1.raiden.on_messages([reveal_secret])
示例#3
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses,
                                              transport_protocol):
    """ A RevealSecret message received after a Unlock message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    token_network_registry_address = app0.raiden.default_registry.address
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(app0), token_network_registry_address, token)
    payment_status = app0.raiden.mediated_transfer_async(
        token_network_address,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier)
    with watch_for_unlock_failures(*raiden_network):
        assert payment_status.payment_done.wait()

    event = search_for_item(app1.raiden.wal.storage.get_events(),
                            SendSecretReveal, {})
    assert event

    reveal_secret = RevealSecret(
        message_identifier=make_message_identifier(),
        secret=event.secret,
        signature=EMPTY_SIGNATURE,
    )
    app2.raiden.sign(reveal_secret)

    if transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError("Unknown TransportProtocol")
示例#4
0
def test_close_regression(raiden_network, deposit, token_addresses):
    """ The python api was using the wrong balance proof to close the channel,
    thus the close was failing if a transfer was made.
    """
    app0, app1 = raiden_network
    token_address = token_addresses[0]

    api1 = RaidenAPI(app0.raiden)
    api2 = RaidenAPI(app1.raiden)

    registry_address = app0.raiden.default_registry.address
    channel_list = api1.get_channel_list(registry_address, token_address,
                                         app1.raiden.address)
    channel12 = channel_list[0]

    token_proxy = app0.raiden.proxy_manager.token(token_address,
                                                  BLOCK_ID_LATEST)
    node1_balance_before = token_proxy.balance_of(api1.address)
    node2_balance_before = token_proxy.balance_of(api2.address)

    # Initialize app2 balance proof and close the channel
    amount = PaymentAmount(10)
    identifier = PaymentID(42)
    secret, secrethash = factories.make_secret_with_hash()
    timeout = block_offset_timeout(app1.raiden, "Transfer timed out.")
    with watch_for_unlock_failures(*raiden_network), timeout:
        assert api1.transfer_and_wait(
            registry_address=registry_address,
            token_address=token_address,
            amount=amount,
            target=TargetAddress(api2.address),
            identifier=identifier,
            secret=secret,
        )
        timeout.exception_to_throw = ValueError(
            "Waiting for transfer received success in the WAL timed out.")
        result = waiting.wait_for_received_transfer_result(
            raiden=app1.raiden,
            payment_identifier=identifier,
            amount=amount,
            retry_timeout=app1.raiden.alarm.sleep_time,
            secrethash=secrethash,
        )

    msg = f"Unexpected transfer result: {str(result)}"
    assert result == waiting.TransferWaitResult.UNLOCKED, msg

    api2.channel_close(registry_address, token_address, api1.address)

    waiting.wait_for_settle(
        app0.raiden,
        app0.raiden.default_registry.address,
        token_address,
        [channel12.identifier],
        app0.raiden.alarm.sleep_time,
    )
    node1_expected_balance = node1_balance_before + deposit - amount
    node2_expected_balance = node2_balance_before + deposit + amount
    assert token_proxy.balance_of(api1.address) == node1_expected_balance
    assert token_proxy.balance_of(api2.address) == node2_expected_balance
示例#5
0
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"]
示例#6
0
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"]
示例#7
0
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()
示例#8
0
def test_echo_node_response(token_addresses, raiden_chain, retry_timeout):
    app0, app1, echo_app = raiden_chain
    token_address = token_addresses[0]
    registry_address = echo_app.raiden.default_registry.address

    echo_api = RaidenAPI(echo_app.raiden)
    echo_node = EchoNode(echo_api, token_address)

    message_handler = WaitForMessage()
    echo_app.raiden.message_handler = message_handler

    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()

    transfer_timeout = 10

    wait_for = list()
    for num, app in enumerate([app0, app1]):
        amount = PaymentAmount(1 + num)
        identifier = PaymentID(10 ** (num + 1))
        secret, secrethash = make_secret_with_hash()

        payment_status = RaidenAPI(app.raiden).transfer_async(
            registry_address=registry_address,
            token_address=token_address,
            amount=amount,
            target=echo_app.raiden.address,
            identifier=identifier,
            secret=secret,
            secrethash=secrethash,
        )

        wait = message_handler.wait_for_message(Unlock, {"secret": secret})
        wait_for.append((wait, app.raiden.address, amount, identifier))

        msg = (
            f"Transfer {identifier} from "
            f"{to_checksum_address(app.raiden.address)} to "
            f"{to_checksum_address(echo_app.raiden.address)} timed out after "
            f"{transfer_timeout}"
        )
        timeout = gevent.Timeout(transfer_timeout, exception=RuntimeError(msg))
        with watch_for_unlock_failures(*raiden_chain), timeout:
            payment_status.payment_done.wait()

        echo_identifier = PaymentID(identifier + amount)
        msg = (
            f"Response transfer {echo_identifier} from echo node "
            f"{to_checksum_address(echo_app.raiden.address)} to "
            f"{to_checksum_address(app.raiden.address)} timed out after "
            f"{transfer_timeout}"
        )
        with gevent.Timeout(transfer_timeout, exception=RuntimeError(msg)):
            result = wait_for_received_transfer_result(
                raiden=app.raiden,
                payment_identifier=echo_identifier,
                amount=amount,
                retry_timeout=retry_timeout,
                secrethash=secrethash,
            )
            assert result == TransferWaitResult.UNLOCKED

    for wait, sender, amount, ident in wait_for:
        wait.wait()
        assert search_for_item(
            echo_app.raiden.wal.storage.get_events(),
            EventPaymentReceivedSuccess,
            {
                "amount": amount,
                "identifier": ident,
                "initiator": sender,
                "token_network_registry_address": registry_address,
            },
        )

    echo_node.stop()
示例#9
0
def test_echo_node_lottery(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, app3, echo_app, app4, app5, app6 = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()

    transfer_timeout = 10

    # Let 6 participants enter the pool
    amount = 7
    for num, app in enumerate([app0, app1, app2, app3, app4, app5]):
        identifier = 100 * num
        with watch_for_unlock_failures(*raiden_chain):
            transfer_and_await(
                app=app,
                token_address=token_address,
                target=echo_app.raiden.address,
                amount=amount,
                identifier=identifier,
                timeout=transfer_timeout,
            )

    # test duplicated identifier + amount is ignored
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app5,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=500,  # app5 used this identifier before
            timeout=transfer_timeout,
        )

    # test pool size querying
    pool_query_identifier = 77  # unused identifier different from previous one
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app5,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=pool_query_identifier,
            timeout=transfer_timeout,
        )

    # fill the pool
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app6,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=600,
            timeout=transfer_timeout,
        )

    def get_echoed_transfer(sent_transfer) -> Optional[EventPaymentReceivedSuccess]:
        """For a given transfer sent to echo node, get the corresponding echoed transfer"""
        app = address_to_app[sent_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address
        )
        for event in events:
            if not type(event) == EventPaymentReceivedSuccess:
                continue
            assert isinstance(event, EventPaymentReceivedSuccess), MYPY_ANNOTATION
            if not (
                event.initiator == echo_app.raiden.address
                and event.identifier == sent_transfer.identifier + event.amount
            ):
                continue

            return event

        return None

    def received_events_when_len(size: int) -> Optional[List[EventPaymentReceivedSuccess]]:
        """Return transfers received from echo_node when there's size transfers"""
        received_events = []
        # Check that payout was generated and pool_size_query answered
        for handled_transfer in echo_node.seen_transfers:
            event = get_echoed_transfer(handled_transfer)
            if not event:
                continue

            received_events.append(event)

        log.debug(
            "Checking number of received events",
            received_events=received_events,
            expected_size=size,
            actual_size=len(received_events),
            seen_transfers=echo_node.seen_transfers,
            received_transfers=received_events,
        )
        if len(received_events) == size:
            return received_events

        return None

    # wait for the expected echoed transfers to be handled
    received = wait_until(func=lambda: received_events_when_len(2), wait_for=network_wait)
    assert received

    received.sort(key=lambda transfer: transfer.amount)

    pool_query = received[0]
    assert pool_query.amount == 6
    assert pool_query.identifier == pool_query_identifier + 6

    winning_transfer = received[1]
    assert winning_transfer.initiator == echo_app.raiden.address
    assert winning_transfer.amount == 49
    assert (winning_transfer.identifier - 49) % 10 == 0

    echo_node.stop()
示例#10
0
def test_secret_revealed_on_chain(raiden_chain, deposit, settle_timeout,
                                  token_addresses, retry_interval_initial):
    """ A node must reveal the secret on-chain if it's known and the channel is closed. """
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(app0), app0.raiden.default_registry.address,
        token_address)
    assert token_network_address

    amount = 10
    identifier = 1
    target = app2.raiden.address
    secret, secrethash = factories.make_secret_with_hash()

    # Reveal the secret, but do not unlock it off-chain
    app1_hold_event_handler = app1.raiden.raiden_event_handler
    app1_hold_event_handler.hold_unlock_for(secrethash=secrethash)

    app0.raiden.start_mediated_transfer_with_secret(
        token_network_address=token_network_address,
        amount=amount,
        target=target,
        identifier=identifier,
        secret=secret,
    )

    with watch_for_unlock_failures(*raiden_chain), block_offset_timeout(
            app0.raiden):
        wait_for_state_change(app2.raiden, ReceiveSecretReveal,
                              {"secrethash": secrethash},
                              retry_interval_initial)

    channel_state2_1 = get_channelstate(app2, app1, token_network_address)
    pending_lock = channel_state2_1.partner_state.secrethashes_to_unlockedlocks.get(
        secrethash)
    msg = "The lock must be registered in unlocked locks since the secret is known"
    assert pending_lock is not None, msg

    # The channels are out-of-sync. app1 has sent the unlock, however we are
    # intercepting it and app2 has not received the updated balance proof

    # Close the channel. This must register the secret on chain
    balance_proof = channel_state2_1.partner_state.balance_proof
    assert isinstance(balance_proof, BalanceProofSignedState)
    channel_close_event = ContractSendChannelClose(
        canonical_identifier=channel_state2_1.canonical_identifier,
        balance_proof=balance_proof,
        triggered_by_block_hash=app0.raiden.rpc_client.
        blockhash_from_blocknumber(BLOCK_ID_LATEST),
    )
    current_state = app2.raiden.wal.state_manager.current_state
    app2.raiden.raiden_event_handler.on_raiden_events(
        raiden=app2.raiden,
        chain_state=current_state,
        events=[channel_close_event])

    settle_expiration = (app0.raiden.rpc_client.block_number() +
                         settle_timeout +
                         DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)
    app0.raiden.proxy_manager.client.wait_until_block(
        target_block_number=settle_expiration)

    # TODO:
    # - assert on the transferred amounts on-chain (for settle and unlock)

    # The channel app0-app1 should continue with the protocol off-chain, once
    # the secret is released on-chain by app2
    assert_synced_channel_state(token_network_address, app0, deposit - amount,
                                [], app1, deposit + amount, [])

    with watch_for_unlock_failures(*raiden_chain), gevent.Timeout(10):
        wait_for_state_change(
            app2.raiden,
            ContractReceiveSecretReveal,
            {"secrethash": secrethash},
            retry_interval_initial,
        )
示例#11
0
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)
示例#12
0
def test_api_payments_with_lock_timeout(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
    number_of_nodes = 2
    reveal_timeout = number_of_nodes * 4 + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS
    settle_timeout = 39

    # try lock_timeout = reveal_timeout - should not work
    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),
            "lock_timeout": str(reveal_timeout),
        },
    )
    response = request.send().response
    assert_response_with_error(response, status_code=HTTPStatus.CONFLICT)

    # try lock_timeout = reveal_timeout * 2  - should  work.
    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),
            "lock_timeout": str(2 * reveal_timeout),
        },
    )
    with watch_for_unlock_failures(*raiden_network):
        response = request.send().response
    assert_proper_response(response, status_code=HTTPStatus.OK)

    # try lock_timeout = settle_timeout - should work.
    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),
            "lock_timeout": str(settle_timeout),
        },
    )
    response = request.send().response
    assert_proper_response(response, status_code=HTTPStatus.OK)

    # try lock_timeout = settle_timeout+1 - should not work.
    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": amount,
            "identifier": identifier,
            "lock_timeout": settle_timeout + 1
        },
    )
    response = request.send().response
    assert_response_with_error(response, status_code=HTTPStatus.CONFLICT)
示例#13
0
def test_api_payments_with_resolver(
        api_server_test_instance: APIServer,
        raiden_network,
        token_addresses,
        resolvers,  # pylint: disable=unused-argument
):

    _, app1 = raiden_network
    amount = 100
    identifier = 42
    token_address = token_addresses[0]
    target_address = app1.raiden.address
    secret = factories.make_secret()
    secret_hash = sha256_secrethash(secret)

    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),
    }

    # payment with secret_hash when both resolver and initiator don't have the secret

    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_hash": encode_hex(secret_hash),
        },
    )
    response = request.send().response
    assert_proper_response(response, status_code=HTTPStatus.CONFLICT)
    assert payment == payment

    # payment with secret where the resolver doesn't have the secret. Should work.

    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": encode_hex(secret)
        },
    )
    response = request.send().response
    assert_proper_response(response, status_code=HTTPStatus.OK)
    assert payment == payment

    # payment with secret_hash where the resolver has the secret. Should work.

    secret = Secret(
        decode_hex(
            "0x2ff886d47b156de00d4cad5d8c332706692b5b572adfe35e6d2f65e92906806e"
        ))
    secret_hash = sha256_secrethash(secret)

    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_hash": encode_hex(secret_hash),
        },
    )
    with watch_for_unlock_failures(*raiden_network):
        response = request.send().response
    assert_proper_response(response, status_code=HTTPStatus.OK)
    assert payment == payment
示例#14
0
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,
        )
示例#15
0
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
            },
        )
示例#16
0
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()
示例#17
0
def test_send_queued_messages(  # pylint: disable=unused-argument
        raiden_network, deposit, token_addresses, network_wait):
    """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)
    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

    number_of_transfers = 7
    amount_per_transfer = 1
    total_transferred_amount = TokenAmount(amount_per_transfer *
                                           number_of_transfers)

    # Make sure none of the transfers will be sent before the restart
    transfers = []
    for secret_seed in range(number_of_transfers):
        secret = make_secret(secret_seed)
        secrethash = sha256_secrethash(secret)
        transfers.append((create_default_identifier(), amount_per_transfer,
                          secret, secrethash))

        app0.raiden.raiden_event_handler.hold(
            SendLockedTransfer,
            {"transfer": {
                "lock": {
                    "secrethash": secrethash
                }
            }})

    for identifier, amount, secret, _ in transfers:
        app0.raiden.mediated_transfer_async(
            token_network_address=token_network_address,
            amount=amount,
            target=app1.raiden.address,
            identifier=identifier,
            secret=secret,
        )

    app0.stop()

    # Restart the app. The pending transfers must be processed.
    new_transport = MatrixTransport(app0.raiden.config["transport"]["matrix"])
    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_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=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        routing_mode=RoutingMode.PRIVATE,
    )

    del app0
    app0_restart.start()

    # XXX: There is no synchronization among the app and the test, so it is
    # possible between `start` and the check bellow that some of the transfers
    # have completed, making it flaky.
    #
    # Make sure the transfers are in the queue and fail otherwise.
    # chain_state = views.state_from_raiden(app0_restart.raiden)
    # for _, _, _, secrethash in transfers:
    #     msg = "The secrethashes of the pending transfers must be in the queue after a restart."
    #     assert secrethash in chain_state.payment_mapping.secrethashes_to_task, msg

    with watch_for_unlock_failures(*raiden_network):
        exception = RuntimeError(
            "Timeout while waiting for balance update for app0")
        with gevent.Timeout(20, exception=exception):
            waiting.wait_for_payment_balance(
                raiden=app0_restart.raiden,
                token_network_registry_address=token_network_registry_address,
                token_address=token_address,
                partner_address=app1.raiden.address,
                target_address=app1.raiden.address,
                target_balance=total_transferred_amount,
                retry_timeout=network_wait,
            )
        exception = RuntimeError(
            "Timeout while waiting for balance update for app1")
        with gevent.Timeout(20, exception=exception):
            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=total_transferred_amount,
                retry_timeout=network_wait,
            )

    assert_synced_channel_state(
        token_network_address,
        app0_restart,
        deposit - total_transferred_amount,
        [],
        app1,
        deposit + total_transferred_amount,
        [],
    )
    new_transport.stop()
示例#18
0
def test_send_queued_messages_after_restart(  # pylint: disable=unused-argument
    raiden_network: List[RaidenService],
    restart_node: RestartNode,
    deposit: TokenAmount,
    token_addresses: List[TokenAddress],
    network_wait: float,
):
    """Test re-sending of undelivered messages on node restart"""
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_raiden(app0)
    token_network_registry_address = app0.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

    number_of_transfers = 7
    amount_per_transfer = PaymentAmount(1)
    total_transferred_amount = TokenAmount(amount_per_transfer *
                                           number_of_transfers)

    # Make sure none of the transfers will be sent before the restart
    transfers = []
    for secret_seed in range(number_of_transfers):
        secret = make_secret(secret_seed)
        secrethash = sha256_secrethash(secret)
        transfers.append((create_default_identifier(), amount_per_transfer,
                          secret, secrethash))

        assert isinstance(app0.raiden_event_handler,
                          HoldRaidenEventHandler)  # for mypy
        app0.raiden_event_handler.hold(
            SendLockedTransfer,
            {"transfer": {
                "lock": {
                    "secrethash": secrethash
                }
            }})

    for identifier, amount, secret, _ in transfers:
        app0.mediated_transfer_async(
            token_network_address=token_network_address,
            amount=amount,
            target=TargetAddress(app1.address),
            identifier=identifier,
            secret=secret,
        )

    app0.stop()

    # Restart the app. The pending transfers must be processed.
    new_transport = MatrixTransport(config=app0.config.transport,
                                    environment=app0.config.environment_type)
    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()
    app0_restart = RaidenService(
        config=app0.config,
        rpc_client=app0.rpc_client,
        proxy_manager=app0.proxy_manager,
        query_start_block=BlockNumber(0),
        raiden_bundle=RaidenBundle(
            app0.default_registry,
            app0.default_secret_registry,
        ),
        services_bundle=app0.default_services_bundle,
        transport=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        routing_mode=RoutingMode.PRIVATE,
    )

    del app0
    restart_node(app0_restart)

    # XXX: There is no synchronization among the app and the test, so it is
    # possible between `start` and the check below that some of the transfers
    # have completed, making it flaky.
    #
    # Make sure the transfers are in the queue and fail otherwise.
    chain_state = views.state_from_raiden(app0_restart)
    for _, _, _, secrethash in transfers:
        msg = "The secrethashes of the pending transfers must be in the queue after a restart."
        assert secrethash in chain_state.payment_mapping.secrethashes_to_task, msg

    timeout = block_offset_timeout(
        app1, "Timeout waiting for balance update of app0")
    with watch_for_unlock_failures(*raiden_network), timeout:
        waiting.wait_for_payment_balance(
            raiden=app0_restart,
            token_network_registry_address=token_network_registry_address,
            token_address=token_address,
            partner_address=app1.address,
            target_address=app1.address,
            target_balance=total_transferred_amount,
            retry_timeout=network_wait,
        )
        timeout.exception_to_throw = ValueError(
            "Timeout waiting for balance update of app1")
        waiting.wait_for_payment_balance(
            raiden=app1,
            token_network_registry_address=token_network_registry_address,
            token_address=token_address,
            partner_address=app0_restart.address,
            target_address=app1.address,
            target_balance=total_transferred_amount,
            retry_timeout=network_wait,
        )

    assert_synced_channel_state(
        token_network_address,
        app0_restart,
        Balance(deposit - total_transferred_amount),
        [],
        app1,
        Balance(deposit + total_transferred_amount),
        [],
    )
    new_transport.stop()