Example #1
0
def wait_for_token_network(
    raiden: "RaidenService",
    token_network_registry_address: TokenNetworkRegistryAddress,
    token_address: TokenAddress,
    retry_timeout: float,
) -> None:  # pragma: no unittest
    """Wait until the token network is visible to the RaidenService.

    Note:
        This does not time out, use gevent.Timeout.
    """
    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(raiden), token_network_registry_address,
        token_address)
    log_details = {
        "token_network_registry_address":
        to_checksum_address(token_network_registry_address),
        "token_address":
        to_checksum_address(token_address),
    }
    while token_network is None:
        assert raiden, ALARM_TASK_ERROR_MSG
        assert raiden.alarm, ALARM_TASK_ERROR_MSG

        log.debug("wait_for_token_network", **log_details)
        gevent.sleep(retry_timeout)
        token_network = views.get_token_network_by_token_address(
            views.state_from_raiden(raiden), token_network_registry_address,
            token_address)
Example #2
0
def wait_for_payment_network(
    raiden: "RaidenService",
    payment_network_id: PaymentNetworkID,
    token_address: TokenAddress,
    retry_timeout: float,
) -> None:
    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(raiden), payment_network_id, token_address
    )
    while token_network is None:
        gevent.sleep(retry_timeout)
        token_network = views.get_token_network_by_token_address(
            views.state_from_raiden(raiden), payment_network_id, token_address
        )
Example #3
0
def wait_for_payment_network(
        raiden: RaidenService,
        payment_network_id: typing.PaymentNetworkID,
        token_address: typing.TokenAddress,
        retry_timeout: float,
) -> None:
    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(raiden),
        payment_network_id,
        token_address,
    )
    while token_network is None:
        gevent.sleep(retry_timeout)
        token_network = views.get_token_network_by_token_address(
            views.state_from_raiden(raiden),
            payment_network_id,
            token_address,
        )
Example #4
0
def wait_for_payment_network(
    raiden: RaidenService,
    payment_network_id: typing.PaymentNetworkID,
    token_address: typing.TokenAddress,
    poll_timeout: typing.NetworkTimeout,
) -> None:
    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(raiden),
        payment_network_id,
        token_address,
    )
    while token_network is None:
        gevent.sleep(poll_timeout)
        token_network = views.get_token_network_by_token_address(
            views.state_from_raiden(raiden),
            payment_network_id,
            token_address,
        )
Example #5
0
def wait_for_channel_in_states(raiden: "RaidenService",
                               payment_network_id: PaymentNetworkID,
                               token_address: TokenAddress,
                               channel_ids: List[ChannelID],
                               retry_timeout: float,
                               target_states: Sequence[str],
                               partner_addresses: List[Address]) -> None:
    """Wait until all channels are in `target_states`.

    Raises:
        ValueError: If the token_address is not registered in the
            payment_network.

    Note:
        This does not time out, use gevent.Timeout.
    """
    chain_state = views.state_from_raiden(raiden)
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_id,
        token_address=token_address)

    if token_network is None:
        raise ValueError(
            f"The token {token_address} is not registered on the network {payment_network_id}."
        )

    token_network_address = token_network.address

    list_cannonical_ids = [
        CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ) for channel_identifier in channel_ids
    ]

    while list_cannonical_ids:
        assert raiden, ALARM_TASK_ERROR_MSG
        assert raiden.alarm, ALARM_TASK_ERROR_MSG

        canonical_id = list_cannonical_ids[-1]
        chain_state = views.state_from_raiden(raiden)

        channel_state = views.get_channelstate_by_canonical_identifier_and_address(
            chain_state=chain_state,
            canonical_identifier=canonical_id,
            address=partner_addresses[0])

        channel_is_settled = (channel_state is None
                              or channel.get_status(channel_state)
                              in target_states)

        if channel_is_settled:
            list_cannonical_ids.pop()
        else:
            gevent.sleep(retry_timeout)
Example #6
0
def wait_for_channel_in_states(
    raiden: RaidenService,
    payment_network_id: typing.PaymentNetworkID,
    token_address: typing.TokenAddress,
    channel_ids: typing.List[typing.ChannelID],
    retry_timeout: float,
    target_states: typing.Tuple[str],
) -> None:
    """Wait until all channels are in `target_states`.

    Raises:
        ValueError: If the token_address is not registered in the
            payment_network.

    Note:
        This does not time out, use gevent.Timeout.
    """
    chain_state = views.state_from_raiden(raiden)
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_id,
        token_address=token_address,
    )

    if token_network is None:
        raise ValueError(
            f'The token {token_address} is not registered on the network {payment_network_id}.',
        )

    token_network_address = token_network.address

    list_cannonical_ids = [
        CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ) for channel_identifier in channel_ids
    ]

    while list_cannonical_ids:
        canonical_id = list_cannonical_ids[-1]
        chain_state = views.state_from_raiden(raiden)

        channel_state = views.get_channelstate_by_canonical_identifier(
            chain_state=chain_state,
            canonical_identifier=canonical_id,
        )

        channel_is_settled = (channel_state is None
                              or channel.get_status(channel_state)
                              in target_states)

        if channel_is_settled:
            list_cannonical_ids.pop()
        else:
            gevent.sleep(retry_timeout)
Example #7
0
def create_route_state_for_route(apps: List[RaidenService],
                                 token_address: TokenAddress,
                                 fee_estimate: FeeAmount) -> RouteState:
    assert len(apps) > 1, "Need at least two nodes for a route"
    route = [app.address for app in apps]

    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(apps[0]),
        apps[0].default_registry.address,
        token_address,
    )
    assert token_network

    return RouteState(route=route, estimated_fee=fee_estimate)
Example #8
0
def channel_state_until_state_change(
    raiden,
    payment_network_identifier: typing.PaymentNetworkID,
    token_address: typing.TokenAddress,
    channel_identifier: typing.ChannelID,
    state_change_identifier: int,
) -> typing.Optional[NettingChannelState]:
    """ Go through WAL state changes until a certain balance hash is found. """
    wal = restore_to_state_change(
        transition_function=node.state_transition,
        storage=raiden.wal.storage,
        state_change_identifier=state_change_identifier,
    )

    msg = 'There is a state change, therefore the state must not be None'
    assert wal.state_manager.current_state is not None, msg

    chain_state = wal.state_manager.current_state
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_identifier,
        token_address=token_address,
    )

    if not token_network:
        return None

    token_network_address = token_network.address

    canonical_identifier = CanonicalIdentifier(
        chain_identifier=chain_state.chain_id,
        token_network_address=token_network_address,
        channel_identifier=channel_identifier,
    )
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=wal.state_manager.current_state,
        canonical_identifier=canonical_identifier,
    )

    if not channel_state:
        raise RaidenUnrecoverableError(
            f"Channel was not found before state_change {state_change_identifier}",
        )

    return channel_state
Example #9
0
def test_regression_revealsecret_after_secret(
        raiden_network: List[RaidenService],
        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.default_registry.address
    token_network = views.get_token_network_by_token_address(
        views.state_from_raiden(app0), token_network_registry_address, token)
    assert token_network, "The fixtures must register the token"

    payment_status = app0.mediated_transfer_async(
        token_network.address,
        amount=PaymentAmount(1),
        target=TargetAddress(app2.address),
        identifier=identifier,
        route_states=[
            RouteState(route=[app0.address, app1.address, app2.address])
        ],
    )
    with watch_for_unlock_failures(*raiden_network):
        assert payment_status.payment_done.wait()

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

    reveal_secret = RevealSecret(
        message_identifier=make_message_identifier(),
        secret=event.secret,
        signature=EMPTY_SIGNATURE,
    )
    app2.sign(reveal_secret)
    app1.on_messages([reveal_secret])
Example #10
0
def wait_for_channel_in_states(
    raiden: "RaidenService",
    token_network_registry_address: TokenNetworkRegistryAddress,
    token_address: TokenAddress,
    channel_ids: List[ChannelID],
    retry_timeout: float,
    target_states: Sequence[ChannelState],
) -> None:
    """Wait until all channels are in `target_states`.

    Raises:
        ValueError: If the token_address is not registered in the
            token_network_registry.

    Note:
        This does not time out, use gevent.Timeout.
    """
    chain_state = views.state_from_raiden(raiden)
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        token_network_registry_address=token_network_registry_address,
        token_address=token_address,
    )

    if token_network is None:
        raise ValueError(
            f"The token {to_checksum_address(token_address)} is not registered on "
            f"the network {to_checksum_address(token_network_registry_address)}."
        )

    token_network_address = token_network.address

    list_cannonical_ids = [
        CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ) for channel_identifier in channel_ids
    ]

    log_details = {
        "token_network_registry_address":
        to_checksum_address(token_network_registry_address),
        "token_address":
        to_checksum_address(token_address),
        "list_cannonical_ids":
        list_cannonical_ids,
        "target_states":
        target_states,
    }

    while list_cannonical_ids:
        assert raiden, ALARM_TASK_ERROR_MSG
        assert raiden.alarm, ALARM_TASK_ERROR_MSG

        canonical_id = list_cannonical_ids[-1]
        chain_state = views.state_from_raiden(raiden)

        channel_state = views.get_channelstate_by_canonical_identifier(
            chain_state=chain_state, canonical_identifier=canonical_id)

        channel_is_settled = (channel_state is None
                              or channel.get_status(channel_state)
                              in target_states)

        if channel_is_settled:
            list_cannonical_ids.pop()
        else:
            log.debug("wait_for_channel_in_states", **log_details)
            gevent.sleep(retry_timeout)
def test_participant_selection(raiden_network, token_addresses):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=100,
    )

    # Test invalid argument values
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=-1,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=2,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=-1,
        )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        ) for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address, ) for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    exception = AssertionError('Unsaturated connection managers',
                               unsaturated_connection_managers)
    with gevent.Timeout(120, exception):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address,
                                        token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                chain_state=node_state,
                token_network_id=network_state.address,
                from_address=app.raiden.address,
                to_address=target.raiden.address,
                amount=1,
                previous_address=None,
                config={},
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    for app in raiden_network:
        sender = app.raiden
        sender_channel = next(
            (channel_state
             for channel_state in RaidenAPI(sender).get_channel_list(
                 registry_address=registry_address,
                 token_address=token_address,
             ) if channel_state.our_state.contract_balance > 0
             and channel_state.partner_state.contract_balance > 0),
            None)  # choose a fully funded channel from sender
        if sender_channel:
            break
    registry_address = sender.default_registry.address

    receiver = next(
        app.raiden for app in raiden_network
        if app.raiden.address == sender_channel.partner_state.address)

    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (sender_channel.settle_timeout *
               connection_manager.raiden.chain.estimate_blocktime() * 10)

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        # sender leaves the network
        RaidenAPI(sender).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    connection_manager.raiden.chain.wait_until_block(
        target_block_number=before_block + wait_blocks, )
    receiver.chain.wait_until_block(target_block_number=before_block +
                                    wait_blocks, )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    # because of timing, channel may already have been cleaned
    assert not receiver_channel or receiver_channel[
        0].settle_transaction is not None
Example #12
0
def get_best_routes(
    node_state: 'NodeState',
    payment_network_id: typing.address,
    token_address: typing.address,
    from_address: typing.address,
    to_address: typing.address,
    amount: int,
    previous_address: typing.address,
) -> List[RouteState]:
    """ Returns a list of channels that can be used to make a transfer.

    This will filter out channels that are not open and don't have enough
    capacity.
    """
    # TODO: Route ranking.
    # Rate each route to optimize the fee price/quality of each route and add a
    # rate from in the range [0.0,1.0].

    available_routes = list()

    token_network = views.get_token_network_by_token_address(
        node_state,
        payment_network_id,
        token_address,
    )

    network_statuses = views.get_networkstatuses(node_state)

    neighbors_heap = get_ordered_partners(
        token_network.network_graph.network,
        from_address,
        to_address,
    )

    if not neighbors_heap and log.isEnabledFor(logging.WARNING):
        log.warn(
            'No routes available from %s to %s',
            pex(from_address),
            pex(to_address),
        )

    while neighbors_heap:
        _, partner_address = heappop(neighbors_heap)

        channel_state = views.get_channelstate_for(
            node_state,
            payment_network_id,
            token_address,
            partner_address,
        )

        # don't send the message backwards
        if partner_address == previous_address:
            continue

        if channel.get_status(channel_state) != CHANNEL_STATE_OPENED:
            if log.isEnabledFor(logging.INFO):
                log.info(
                    'channel %s - %s is not opened, ignoring',
                    pex(from_address),
                    pex(partner_address),
                )
            continue

        distributable = channel.get_distributable(
            channel_state.our_state,
            channel_state.partner_state,
        )

        if amount > distributable:
            if log.isEnabledFor(logging.INFO):
                log.info(
                    'channel %s - %s doesnt have enough funds [%s], ignoring',
                    pex(from_address),
                    pex(partner_address),
                    amount,
                )
            continue

        network_state = network_statuses.get(partner_address,
                                             NODE_NETWORK_UNKNOWN)
        if network_state != NODE_NETWORK_REACHABLE:
            if log.isEnabledFor(logging.INFO):
                log.info(
                    'partner for channel %s - %s is not %s, ignoring',
                    pex(from_address),
                    pex(partner_address),
                    NODE_NETWORK_REACHABLE,
                )
            continue

        route_state = RouteState(partner_address, channel_state.identifier)
        available_routes.append(route_state)

    return available_routes
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,
        )
Example #14
0
def test_participant_selection(raiden_network, token_addresses, skip_if_tester):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address,
        token_address,
        100,
    )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        )

        for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address,
        ) for app in raiden_network
    ]

    assert wait_for_saturated(
        connection_managers,
        registry_address,
        token_address,
    ) is True

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                node_state,
                network_state.address,
                app.raiden.address,
                target.raiden.address,
                1,
                None,
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    sender = raiden_network[-1].raiden
    receiver = raiden_network[0].raiden

    registry_address = sender.default_registry.address
    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    # assert there is a direct channel sender -> receiver
    sender_channel = RaidenAPI(sender).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=receiver.address,
    )
    assert len(sender_channel) == 1
    sender_channel = sender_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (
        sender_channel.settle_timeout *
        connection_manager.raiden.chain.estimate_blocktime() *
        10
    )

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        RaidenAPI(raiden_network[0].raiden).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    wait_until_block(
        connection_manager.raiden.chain,
        before_block + wait_blocks,
    )
    wait_until_block(
        receiver.chain,
        before_block + wait_blocks,
    )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert receiver_channel[0].settle_transaction is not None
Example #15
0
def test_connect_does_not_open_channels_with_offline_nodes(
        raiden_network, token_addresses):
    """
    Test that using the connection manager to connect to a token network
    does not open channels with offline nodes

    Test for https://github.com/raiden-network/raiden/issues/5583
    """
    # pylint: disable=too-many-locals
    registry_address = raiden_network[0].raiden.default_registry.address
    token_address = token_addresses[0]
    app0, app1, _, _ = raiden_network
    offline_node = app0
    target_channels_num = 1

    # 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(app0.raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=TokenAmount(100),
        initial_channel_target=target_channels_num,
    )

    # First node will now go offline
    offline_node.stop()
    offline_node.raiden.greenlet.get()
    assert not offline_node.raiden

    # Call the connect endpoint for the second node
    RaidenAPI(app1.raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=TokenAmount(100),
        initial_channel_target=target_channels_num,
    )
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_raiden(app1.raiden),
        token_network_registry_address=registry_address,
        token_address=token_address,
    )
    # and wait until connections are done. This should connect to an offline node
    # and create the first online discoverable
    manager = app1.raiden.connection_manager_for_token_network(
        token_network_address)
    exception = AssertionError("Unsaturated connection manager", manager)
    with gevent.Timeout(120, exception):
        if not is_manager_saturated(manager, registry_address, token_address):
            gevent.sleep(1)

    # Call the connect endpoint for all but the two first nodes
    connect_greenlets = set(
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
            target_channels_num,
        ) for app in raiden_network[2:])
    gevent.joinall(connect_greenlets, raise_error=True)

    connection_managers = [
        app.raiden.connection_manager_for_token_network(token_network_address)
        for app in raiden_network[2:]
    ]

    # Wait until channels are opened and connections are done
    unsaturated_connection_managers = connection_managers[2:]
    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)

    for app in raiden_network[2:]:
        # ensure that we did not open a channel with the offline node
        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
        msg = "Each of the last 2 nodes should connect to 1 address"
        assert len(network_state.channelidentifiers_to_channels) == 1, msg
        for _, netchannel in network_state.channelidentifiers_to_channels.items(
        ):
            assert netchannel.partner_state.address != offline_node.raiden.address

    # Call the connect endpoint for all apps again to see this is handled fine.
    # This essentially checks that connecting to bootstrap/offline address again is not a problem
    for app in raiden_network[1:]:
        RaidenAPI(app.raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=TokenAmount(100),
            initial_channel_target=target_channels_num,
        )
Example #16
0
def test_participant_selection(raiden_network, token_addresses, skip_if_tester):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address,
        token_address,
        100,
    )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        )

        for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address,
        ) for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    with gevent.Timeout(
        120,
        AssertionError('Unsaturated connection managers', unsaturated_connection_managers),
    ):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address, token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                node_state,
                network_state.address,
                app.raiden.address,
                target.raiden.address,
                1,
                None,
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    sender = raiden_network[-1].raiden
    receiver = raiden_network[0].raiden

    registry_address = sender.default_registry.address
    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    # assert there is a direct channel sender -> receiver
    sender_channel = RaidenAPI(sender).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=receiver.address,
    )
    assert len(sender_channel) == 1
    sender_channel = sender_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (
        sender_channel.settle_timeout *
        connection_manager.raiden.chain.estimate_blocktime() *
        10
    )

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        RaidenAPI(raiden_network[0].raiden).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    wait_until_block(
        connection_manager.raiden.chain,
        before_block + wait_blocks,
    )
    wait_until_block(
        receiver.chain,
        before_block + wait_blocks,
    )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert receiver_channel[0].settle_transaction is not None