Beispiel #1
0
def next_channel_from_routes(
    available_routes: typing.List[RouteState],
    channelidentifiers_to_channels: typing.ChannelMap,
    transfer_amount: typing.TokenAmount,
) -> typing.Optional[NettingChannelState]:
    """ Returns the first channel that can be used to start the transfer.
    The routing service can race with local changes, so the recommended routes
    must be validated.
    """
    for route in available_routes:
        channel_identifier = route.channel_identifier
        channel_state = channelidentifiers_to_channels.get(channel_identifier)

        if not channel_state:
            continue

        if channel.get_status(channel_state) != CHANNEL_STATE_OPENED:
            continue

        pending_transfers = channel.get_number_of_pending_transfers(
            channel_state.our_state)
        if pending_transfers >= MAXIMUM_PENDING_TRANSFERS:
            continue

        distributable = channel.get_distributable(
            channel_state.our_state,
            channel_state.partner_state,
        )
        if transfer_amount > distributable:
            continue

        if channel.is_valid_amount(channel_state.our_state, transfer_amount):
            return channel_state

    return None
Beispiel #2
0
def next_channel_from_routes(
    available_routes: List['RouteState'],
    channelidentifiers_to_channels: Dict,
    transfer_amount: int,
    timeout_blocks: int,
) -> NettingChannelState:
    """ Returns the first route that may be used to mediated the transfer.
    The routing service can race with local changes, so the recommended routes
    must be validated.
    Args:
        available_routes: Current available routes that may be used, it's
            assumed that the available_routes list is ordered from best to
            worst.
        channelidentifiers_to_channels: Mapping from channel identifier
            to NettingChannelState.
        transfer_amount: The amount of tokens that will be transferred
            through the given route.
        timeout_blocks: Base number of available blocks used to compute
            the lock timeout.
    Returns:
        The next route.
    """
    for route in available_routes:
        channel_identifier = route.channel_identifier
        channel_state = channelidentifiers_to_channels.get(channel_identifier)

        if not channel_state:
            continue

        if channel.get_status(channel_state) != CHANNEL_STATE_OPENED:
            continue

        pending_transfers = channel.get_number_of_pending_transfers(
            channel_state.our_state)
        if pending_transfers >= MAXIMUM_PENDING_TRANSFERS:
            continue

        distributable = channel.get_distributable(
            channel_state.our_state,
            channel_state.partner_state,
        )
        if transfer_amount > distributable:
            continue

        lock_timeout = timeout_blocks - channel_state.reveal_timeout
        if lock_timeout <= 0:
            continue

        if channel.is_valid_amount(channel_state.our_state, transfer_amount):
            return channel_state

    return None
Beispiel #3
0
def is_channel_usable(candidate_channel_state, transfer_amount, lock_timeout):
    pending_transfers = channel.get_number_of_pending_transfers(
        candidate_channel_state.our_state)
    distributable = channel.get_distributable(
        candidate_channel_state.our_state,
        candidate_channel_state.partner_state,
    )

    return (lock_timeout > 0 and channel.get_status(candidate_channel_state)
            == CHANNEL_STATE_OPENED
            and candidate_channel_state.settle_timeout >= lock_timeout
            and candidate_channel_state.reveal_timeout < lock_timeout
            and pending_transfers < MAXIMUM_PENDING_TRANSFERS
            and transfer_amount <= distributable and channel.is_valid_amount(
                candidate_channel_state.our_state, transfer_amount))