Exemplo n.º 1
0
def test_receive_directtransfer_invalidlocksroot(raiden_network,
                                                 token_addresses):
    app0, app1 = raiden_network
    token_address = token_addresses[0]

    channel0 = get_channelstate(app0, app1, token_address)
    balance0 = channel.get_balance(channel0.our_state, channel0.partner_state)
    balance1 = channel.get_balance(channel0.partner_state, channel0.our_state)

    payment_identifier = 1
    invalid_locksroot = UNIT_SECRETHASH
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        message_identifier=message_identifier,
        payment_identifier=payment_identifier,
        nonce=1,
        token=token_address,
        channel=channel_identifier,
        transferred_amount=0,
        recipient=app1.raiden.address,
        locksroot=invalid_locksroot,
    )

    sign_and_inject(
        direct_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    assert_synched_channel_state(token_address, app0, balance0, [], app1,
                                 balance1, [])
Exemplo n.º 2
0
def assert_channel_values(
    channel0: NettingChannelState,
    balance0: Balance,
    pending_locks0: List[HashTimeLockState],
    channel1: NettingChannelState,
    balance1: Balance,
    pending_locks1: List[HashTimeLockState],
) -> None:
    total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance

    our_balance0 = channel.get_balance(channel0.our_state,
                                       channel0.partner_state)
    partner_balance0 = channel.get_balance(channel0.partner_state,
                                           channel0.our_state)
    assert our_balance0 + partner_balance0 == total_token

    our_balance1 = channel.get_balance(channel1.our_state,
                                       channel1.partner_state)
    partner_balance1 = channel.get_balance(channel1.partner_state,
                                           channel1.our_state)
    assert our_balance1 + partner_balance1 == total_token

    locked_amount0 = LockedAmount(sum(lock.amount for lock in pending_locks0))
    locked_amount1 = LockedAmount(sum(lock.amount for lock in pending_locks1))

    assert_balance(channel0, balance0, locked_amount0)
    assert_balance(channel1, balance1, locked_amount1)

    # a participant's outstanding is the other's pending locks.
    assert_locked(channel0, pending_locks0)
    assert_locked(channel1, pending_locks1)

    assert_mirror(channel0, channel1)
    assert_mirror(channel1, channel0)
Exemplo n.º 3
0
def test_receive_directtransfer_invalidlocksroot(raiden_network,
                                                 token_addresses):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    balance0 = channel.get_balance(channel0.our_state, channel0.partner_state)
    balance1 = channel.get_balance(channel0.partner_state, channel0.our_state)

    payment_identifier = 1
    invalid_locksroot = UNIT_SECRETHASH
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=0,
        locked_amount=0,
        recipient=app1.raiden.address,
        locksroot=invalid_locksroot,
    )

    sign_and_inject(
        direct_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        balance0,
        [],
        app1,
        balance1,
        [],
    )
Exemplo n.º 4
0
def get_initial_amount_for_amount_after_fees(
    amount_after_fees: PaymentAmount,
    channels: List[Tuple[NettingChannelState, NettingChannelState]],
) -> Optional[FeesCalculation]:
    """ Calculates the payment amount including fees to be supplied to the given
    channel configuration, so that `amount_after_fees` arrives at the target.

    Note: The channels have to be from the view of the mediator, so for the case
        A -> B -> C this should be [(B->A, B->C)]
    """
    assert len(channels) >= 1, "Need at least one channel pair"

    # Backpropagate fees in mediation scenario
    total = PaymentWithFeeAmount(amount_after_fees)
    fees: List[FeeAmount] = []
    try:
        for channel_in, channel_out in reversed(channels):
            assert isinstance(channel_in, NettingChannelState)
            assert isinstance(channel_out, NettingChannelState)

            balance_in = get_balance(channel_in.our_state,
                                     channel_in.partner_state)
            balance_out = get_balance(channel_out.our_state,
                                      channel_out.partner_state)
            receivable_amount = TokenAmount(channel_in.our_total_deposit +
                                            channel_in.partner_total_deposit -
                                            balance_in)

            before_fees = get_amount_with_fees(
                amount_without_fees=total,
                balance_in=balance_in,
                balance_out=balance_out,
                schedule_in=channel_in.fee_schedule,
                schedule_out=channel_out.fee_schedule,
                receivable_amount=receivable_amount,
            )

            if before_fees is None:
                return None

            fee = FeeAmount(before_fees - total)
            total = PaymentWithFeeAmount(total + fee)
            fees.append(fee)
    except UndefinedMediationFee:
        return None

    return FeesCalculation(total_amount=PaymentWithFeeAmount(total),
                           mediation_fees=fees)
Exemplo n.º 5
0
def assert_synced_channel_state(
    token_network_identifier,
    app0,
    balance0,
    pending_locks0,
    app1,
    balance1,
    pending_locks1,
):
    """ Assert the values of two synced channels.

    Note:
        This assert does not work for an intermediate state, where one message
        hasn't been delivered yet or has been completely lost."""
    # pylint: disable=too-many-arguments

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    channel1 = get_channelstate(app1, app0, token_network_identifier)

    assert channel0.our_state.contract_balance == channel1.partner_state.contract_balance
    assert channel0.partner_state.contract_balance == channel1.our_state.contract_balance

    total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance

    our_balance0 = channel.get_balance(channel0.our_state,
                                       channel0.partner_state)
    partner_balance0 = channel.get_balance(channel0.partner_state,
                                           channel0.our_state)
    assert our_balance0 + partner_balance0 == total_token

    our_balance1 = channel.get_balance(channel1.our_state,
                                       channel1.partner_state)
    partner_balance1 = channel.get_balance(channel1.partner_state,
                                           channel1.our_state)
    assert our_balance1 + partner_balance1 == total_token

    locked_amount0 = sum(lock.amount for lock in pending_locks0)
    locked_amount1 = sum(lock.amount for lock in pending_locks1)

    assert_balance(channel0, balance0, locked_amount0)
    assert_balance(channel1, balance1, locked_amount1)

    # a participant's outstanding is the other's pending locks.
    assert_locked(channel0, pending_locks0)
    assert_locked(channel1, pending_locks1)

    assert_mirror(channel0, channel1)
    assert_mirror(channel1, channel0)
Exemplo n.º 6
0
def assert_balance(from_channel: NettingChannelState, balance: Balance,
                   locked: LockedAmount) -> None:
    """ Assert the from_channel overall token values. """
    assert balance >= 0
    assert locked >= 0

    distributable = balance - locked
    channel_distributable = channel.get_distributable(
        from_channel.our_state, from_channel.partner_state)
    channel_balance = channel.get_balance(from_channel.our_state,
                                          from_channel.partner_state)
    channel_locked_amount = channel.get_amount_locked(from_channel.our_state)

    msg = f"channel balance does not match. Expected: {balance} got: {channel_balance}"
    assert channel_balance == balance, msg

    msg = (f"channel distributable amount does not match. "
           f"Expected: {distributable} got: {channel_distributable}")
    assert channel_distributable == distributable, msg

    msg = f"channel locked amount does not match. Expected: {locked} got: {channel_locked_amount}"
    assert channel_locked_amount == locked, msg

    msg = (f"locked_amount ({locked}) + distributable ({distributable}) "
           f"did not equal the balance ({balance})")
    assert balance == locked + distributable, msg
Exemplo n.º 7
0
def get_node_balances(
        chain_state,
        token_network_address: TokenNetworkAddress) -> List[Tuple[Any]]:
    channels = views.list_all_channelstate(chain_state)
    channels = [
        channel for channel in channels
        if channel.canonical_identifier.token_network_address ==
        to_canonical_address(token_network_address)
    ]
    balances = [(
        channel_state.partner_state.address,
        channel.get_balance(channel_state.our_state,
                            channel_state.partner_state),
        channel.get_balance(channel_state.partner_state,
                            channel_state.our_state),
    ) for channel_state in channels]
    return balances
Exemplo n.º 8
0
def assert_mirror(original, mirror):
    """ Assert that `mirror` has a correct `partner_state` to represent `original`."""
    original_locked_amount = channel.get_amount_locked(original.our_state)
    mirror_locked_amount = channel.get_amount_locked(mirror.partner_state)
    assert original_locked_amount == mirror_locked_amount

    balance0 = channel.get_balance(original.our_state, original.partner_state)
    balance1 = channel.get_balance(mirror.partner_state, mirror.our_state)
    assert balance0 == balance1

    balanceproof0 = channel.get_current_balanceproof(original.our_state)
    balanceproof1 = channel.get_current_balanceproof(mirror.partner_state)
    assert balanceproof0 == balanceproof1

    distributable0 = channel.get_distributable(original.our_state, original.partner_state)
    distributable1 = channel.get_distributable(mirror.partner_state, mirror.our_state)
    assert distributable0 == distributable1
Exemplo n.º 9
0
def assert_mirror(original, mirror):
    """ Assert that `mirror` has a correct `partner_state` to represent `original`."""
    original_locked_amount = channel.get_amount_locked(original.our_state)
    mirror_locked_amount = channel.get_amount_locked(mirror.partner_state)
    assert original_locked_amount == mirror_locked_amount

    balance0 = channel.get_balance(original.our_state, original.partner_state)
    balance1 = channel.get_balance(mirror.partner_state, mirror.our_state)
    assert balance0 == balance1

    balanceproof0 = channel.get_current_balanceproof(original.our_state)
    balanceproof1 = channel.get_current_balanceproof(mirror.partner_state)
    assert balanceproof0 == balanceproof1

    distributable0 = channel.get_distributable(original.our_state, original.partner_state)
    distributable1 = channel.get_distributable(mirror.partner_state, mirror.our_state)
    assert distributable0 == distributable1
Exemplo n.º 10
0
def update_monitoring_service_from_balance_proof(
    raiden: 'RaidenService',
    chain_state: 'ChainState',
    new_balance_proof: BalanceProofSignedState,
) -> None:
    if raiden.config['services']['monitoring_enabled'] is False:
        return

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

    msg = (
        f'Failed to update monitoring service due to inability to find '
        f'channel: {new_balance_proof.channel_identifier} '
        f'token_network_address: {pex(new_balance_proof.token_network_identifier)}.'
    )
    assert channel_state, msg

    balance = channel.get_balance(
        sender=channel_state.our_state,
        receiver=channel_state.partner_state,
    )

    if balance < MONITORING_MIN_CAPACITY:
        log.warn(
            f'Skipping update to Monitoring service. '
            f'Available balance of {balance} is less than configured '
            f'minimum capacity of {MONITORING_MIN_CAPACITY}', )
        return

    rei_balance = raiden.user_deposit.effective_balance(
        raiden.address, 'latest')
    if rei_balance < MONITORING_REWARD:
        rdn_balance = to_rdn(rei_balance)
        rdn_reward = to_rdn(MONITORING_REWARD)
        log.warn(
            f'Skipping update to Monitoring service. '
            f'Your deposit balance {rdn_balance} is less than '
            f'the required monitoring service reward of {rdn_reward}', )
        return

    log.info(
        'Received new balance proof, creating message for Monitoring Service.',
        balance_proof=new_balance_proof,
    )

    monitoring_message = RequestMonitoring.from_balance_proof_signed_state(
        new_balance_proof,
        MONITORING_REWARD,
    )
    monitoring_message.sign(raiden.signer)
    raiden.transport.send_global(
        constants.MONITORING_BROADCASTING_ROOM,
        monitoring_message,
    )
Exemplo n.º 11
0
def assert_partner_state(end_state, partner_state, model):
    """Checks that the stored data for both ends correspond to the model."""
    assert end_state.address == model.participant_address
    assert channel.get_amount_locked(end_state) == model.amount_locked
    assert channel.get_balance(end_state, partner_state) == model.balance
    assert channel.get_distributable(end_state, partner_state) == model.distributable
    assert channel.get_next_nonce(end_state) == model.next_nonce
    assert set(end_state.merkletree.layers[LEAVES]) == set(model.merkletree_leaves)
    assert end_state.contract_balance == model.contract_balance
Exemplo n.º 12
0
def test_receive_directtransfer_invalidlocksroot(raiden_network, token_addresses):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    balance0 = channel.get_balance(channel0.our_state, channel0.partner_state)
    balance1 = channel.get_balance(channel0.partner_state, channel0.our_state)

    payment_identifier = 1
    invalid_locksroot = UNIT_SECRETHASH
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=0,
        locked_amount=0,
        recipient=app1.raiden.address,
        locksroot=invalid_locksroot,
    )

    sign_and_inject(
        direct_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, balance0, [],
        app1, balance1, [],
    )
Exemplo n.º 13
0
    def channel_state_invariants(self):
        """ Check the invariants for the channel state given in the Raiden specification """

        for netting_channel in self.address_to_channel.values():
            our_state = netting_channel.our_state
            partner_state = netting_channel.partner_state

            our_transferred_amount = 0
            if our_state.balance_proof:
                our_transferred_amount = our_state.balance_proof.transferred_amount
                assert our_transferred_amount >= 0

            partner_transferred_amount = 0
            if partner_state.balance_proof:
                partner_transferred_amount = partner_state.balance_proof.transferred_amount
                assert partner_transferred_amount >= 0

            assert channel.get_distributable(our_state, partner_state) >= 0
            assert channel.get_distributable(partner_state, our_state) >= 0

            our_deposit = netting_channel.our_total_deposit
            partner_deposit = netting_channel.partner_total_deposit
            total_deposit = our_deposit + partner_deposit

            our_amount_locked = channel.get_amount_locked(our_state)
            our_balance = channel.get_balance(our_state, partner_state)
            partner_amount_locked = channel.get_amount_locked(partner_state)
            partner_balance = channel.get_balance(partner_state, our_state)

            # invariant (5.1R), add withdrawn amounts when implemented
            assert 0 <= our_amount_locked <= our_balance
            assert 0 <= partner_amount_locked <= partner_balance
            assert our_amount_locked <= total_deposit
            assert partner_amount_locked <= total_deposit

            our_transferred = partner_transferred_amount - our_transferred_amount
            netted_transferred = our_transferred + partner_amount_locked - our_amount_locked

            # invariant (6R), add withdrawn amounts when implemented
            assert 0 <= our_deposit + our_transferred - our_amount_locked <= total_deposit
            assert 0 <= partner_deposit - our_transferred - partner_amount_locked <= total_deposit

            # invariant (7R), add withdrawn amounts when implemented
            assert - our_deposit <= netted_transferred <= partner_deposit
Exemplo n.º 14
0
    def channel_state_invariants(self):
        """ Check the invariants for the channel state given in the Raiden specification """

        for netting_channel in self.address_to_channel.values():
            our_state = netting_channel.our_state
            partner_state = netting_channel.partner_state

            our_transferred_amount = 0
            if our_state.balance_proof:
                our_transferred_amount = our_state.balance_proof.transferred_amount
                assert our_transferred_amount >= 0

            partner_transferred_amount = 0
            if partner_state.balance_proof:
                partner_transferred_amount = partner_state.balance_proof.transferred_amount
                assert partner_transferred_amount >= 0

            assert channel.get_distributable(our_state, partner_state) >= 0
            assert channel.get_distributable(partner_state, our_state) >= 0

            our_deposit = netting_channel.our_total_deposit
            partner_deposit = netting_channel.partner_total_deposit
            total_deposit = our_deposit + partner_deposit

            our_amount_locked = channel.get_amount_locked(our_state)
            our_balance = channel.get_balance(our_state, partner_state)
            partner_amount_locked = channel.get_amount_locked(partner_state)
            partner_balance = channel.get_balance(partner_state, our_state)

            # invariant (5.1R), add withdrawn amounts when implemented
            assert 0 <= our_amount_locked <= our_balance
            assert 0 <= partner_amount_locked <= partner_balance
            assert our_amount_locked <= total_deposit
            assert partner_amount_locked <= total_deposit

            our_transferred = partner_transferred_amount - our_transferred_amount
            netted_transferred = our_transferred + partner_amount_locked - our_amount_locked

            # invariant (6R), add withdrawn amounts when implemented
            assert 0 <= our_deposit + our_transferred - our_amount_locked <= total_deposit
            assert 0 <= partner_deposit - our_transferred - partner_amount_locked <= total_deposit

            # invariant (7R), add withdrawn amounts when implemented
            assert -our_deposit <= netted_transferred <= partner_deposit
Exemplo n.º 15
0
def assert_synched_channel_state(
        token_network_identifier,
        app0,
        balance0,
        pending_locks0,
        app1,
        balance1,
        pending_locks1,
):
    """ Assert the values of two synched channels.

    Note:
        This assert does not work for an intermediate state, where one message
        hasn't been delivered yet or has been completely lost."""
    # pylint: disable=too-many-arguments

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    channel1 = get_channelstate(app1, app0, token_network_identifier)

    assert channel0.our_state.contract_balance == channel1.partner_state.contract_balance
    assert channel0.partner_state.contract_balance == channel1.our_state.contract_balance

    total_token = channel0.our_state.contract_balance + channel1.our_state.contract_balance

    our_balance0 = channel.get_balance(channel0.our_state, channel0.partner_state)
    partner_balance0 = channel.get_balance(channel0.partner_state, channel0.our_state)
    assert our_balance0 + partner_balance0 == total_token

    our_balance1 = channel.get_balance(channel1.our_state, channel1.partner_state)
    partner_balance1 = channel.get_balance(channel1.partner_state, channel1.our_state)
    assert our_balance1 + partner_balance1 == total_token

    locked_amount0 = sum(lock.amount for lock in pending_locks0)
    locked_amount1 = sum(lock.amount for lock in pending_locks1)

    assert_balance(channel0, balance0, locked_amount0)
    assert_balance(channel1, balance1, locked_amount1)

    # a participant's outstanding is the other's pending locks.
    assert_locked(channel0, pending_locks0)
    assert_locked(channel1, pending_locks1)

    assert_mirror(channel0, channel1)
    assert_mirror(channel1, channel0)
Exemplo n.º 16
0
def get_initial_payment_for_final_target_amount(
    final_amount: PaymentAmount, channels: List[NettingChannelState]
) -> Optional[FeesCalculation]:
    """ Calculates the payment amount including fees to be supplied to the given
    channel configuration, so that `final_amount` arrived at the target.

    Note: The channels have to be from the view of the mediator, so for the case
        A -> B -> C this should be [B->A, B->C]
    """
    assert len(channels) >= 1, "Need at least one channel"

    # No fees in direct transfer
    if len(channels) == 1:
        return FeesCalculation(total_amount=PaymentWithFeeAmount(final_amount), mediation_fees=[])

    # Backpropagate fees in mediation scenario
    total = PaymentWithFeeAmount(final_amount)
    fees: List[FeeAmount] = []
    try:
        for channel_in, channel_out in reversed(list(window(channels, 2))):
            assert isinstance(channel_in, NettingChannelState)
            fee_schedule_out = channel_out.fee_schedule
            assert isinstance(channel_out, NettingChannelState)
            fee_schedule_in = channel_in.fee_schedule

            balance_out = get_balance(channel_out.our_state, channel_out.partner_state)
            fee_out = fee_sender(fee_schedule=fee_schedule_out, balance=balance_out, amount=total)

            total += fee_out  # type: ignore

            balance_in = get_balance(channel_in.our_state, channel_in.partner_state)
            fee_in = fee_receiver(fee_schedule=fee_schedule_in, balance=balance_in, amount=total)

            total += fee_in  # type: ignore

            fees.append(FeeAmount(fee_out + fee_in))
    except UndefinedMediationFee:
        return None

    return FeesCalculation(total_amount=PaymentWithFeeAmount(total), mediation_fees=fees)
Exemplo n.º 17
0
def assert_balance(from_channel, balance, locked):
    """ Assert the from_channel overall token values. """
    assert balance >= 0
    assert locked >= 0

    distributable = balance - locked
    channel_distributable = channel.get_distributable(
        from_channel.our_state,
        from_channel.partner_state,
    )

    assert channel.get_balance(from_channel.our_state, from_channel.partner_state) == balance
    assert channel_distributable == distributable
    assert channel.get_amount_locked(from_channel.our_state) == locked

    amount_locked = channel.get_amount_locked(from_channel.our_state)
    assert balance == amount_locked + distributable
Exemplo n.º 18
0
def assert_balance(from_channel, balance, locked):
    """ Assert the from_channel overall token values. """
    assert balance >= 0
    assert locked >= 0

    distributable = balance - locked
    channel_distributable = channel.get_distributable(
        from_channel.our_state,
        from_channel.partner_state,
    )

    assert channel.get_balance(from_channel.our_state, from_channel.partner_state) == balance
    assert channel_distributable == distributable
    assert channel.get_amount_locked(from_channel.our_state) == locked

    amount_locked = channel.get_amount_locked(from_channel.our_state)
    assert balance == amount_locked + distributable
Exemplo n.º 19
0
 def get_balance(self, channel_state):  # pylint: disable=no-self-use
     return channel.get_balance(
         channel_state.our_state,
         channel_state.partner_state,
     )
Exemplo n.º 20
0
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_config):
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(node1),
        node1.raiden.default_registry.address,
        token_address,
    )

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address, api2.address)

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address)
    channels = api1.get_channel_list(registry_address, token_address, api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_identifier)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    event_list1 = api1.get_channel_events(
        token_address,
        channel12.partner_state.address,
        channel12.open_transaction.finished_block_number,
    )
    assert any(
        (
            event['event'] == EVENT_CHANNEL_OPENED and
            is_same_address(
                event['args']['participant1'],
                to_normalized_address(api1.address),
            ) and
            is_same_address(
                event['args']['participant2'],
                to_normalized_address(api2.address),
            )
        )
        for event in event_list1
    )

    token_events = api1.get_token_network_events(
        token_address,
        channel12.open_transaction.finished_block_number,
    )
    assert token_events[0]['event'] == EVENT_CHANNEL_OPENED

    registry_address = api1.raiden.default_registry.address
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address,
        token_address,
        api2.address,
        deposit,
    )

    # let's make sure it's idempotent
    api1.set_total_channel_deposit(
        registry_address,
        token_address,
        api2.address,
        deposit,
    )

    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_channel_events(
        token_address,
        channel12.partner_state.address,
        channel12.open_transaction.finished_block_number,
    )
    assert any(
        (
            event['event'] == EVENT_CHANNEL_DEPOSIT and
            is_same_address(
                event['args']['participant'],
                to_normalized_address(api1.address),
            ) and
            event['args']['total_deposit'] == deposit
        )
        for event in event_list2
    )

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    event_list3 = api1.get_channel_events(
        token_address,
        channel12.partner_state.address,
        channel12.open_transaction.finished_block_number,
    )
    assert len(event_list3) > len(event_list2)
    assert any(
        (
            event['event'] == EVENT_CHANNEL_CLOSED and
            is_same_address(
                event['args']['closing_participant'],
                to_normalized_address(api1.address),
            )
        )
        for event in event_list3
    )
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    settlement_block = (
        channel12.close_transaction.finished_block_number +
        channel12.settle_timeout +
        10  # arbitrary number of additional blocks, used to wait for the settle() call
    )
    wait_until_block(node1.raiden.chain, settlement_block)

    # Load the new state with the channel settled
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
Exemplo n.º 21
0
def test_channel_lifecycle(raiden_network, token_addresses, deposit,
                           transport_config):
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(node1),
        node1.raiden.default_registry.address,
        token_address,
    )

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address,
                                     api2.address)

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address,
                      api2.address)
    channels = api1.get_channel_list(registry_address, token_address,
                                     api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_identifier)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    event_list1 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert any((event['event'] == ChannelEvent.OPENED and is_same_address(
        event['args']['participant1'],
        to_normalized_address(api1.address),
    ) and is_same_address(
        event['args']['participant2'],
        to_normalized_address(api2.address),
    )) for event in event_list1)

    token_events = api1.get_blockchain_events_token_network(token_address, )
    assert token_events[0]['event'] == ChannelEvent.OPENED

    registry_address = api1.raiden.default_registry.address
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address,
        token_address,
        api2.address,
        deposit,
    )

    # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(
            registry_address,
            token_address,
            api2.address,
            deposit,
        )

    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address,
                                 api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert any((event['event'] == ChannelEvent.DEPOSIT and is_same_address(
        event['args']['participant'],
        to_normalized_address(api1.address),
    ) and event['args']['total_deposit'] == deposit) for event in event_list2)

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    event_list3 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert len(event_list3) > len(event_list2)
    assert any((event['event'] == ChannelEvent.CLOSED and is_same_address(
        event['args']['closing_participant'],
        to_normalized_address(api1.address),
    )) for event in event_list3)
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    settlement_block = (
        channel12.close_transaction.finished_block_number +
        channel12.settle_timeout +
        10  # arbitrary number of additional blocks, used to wait for the settle() call
    )
    wait_until_block(node1.raiden.chain, settlement_block)

    state_changes = node1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(
        state_changes, ContractReceiveChannelSettled, {
            'token_network_identifier': token_network_identifier,
            'channel_identifier': channel12.identifier,
        })
Exemplo n.º 22
0
def test_channel_lifecycle(raiden_network, token_addresses, deposit,
                           transport_config):
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(node1),
        node1.raiden.default_registry.address,
        token_address,
    )

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    if transport_config.protocol == TransportProtocol.UDP:
        # nodes don't have a channel, so they are not healthchecking
        assert api1.get_node_network_state(
            api2.address) == NODE_NETWORK_UNKNOWN
        assert api2.get_node_network_state(
            api1.address) == NODE_NETWORK_UNKNOWN
    elif transport_config.protocol == TransportProtocol.MATRIX:
        # with Matrix nodes do not need a health check to know each others reachability
        assert api1.get_node_network_state(
            api2.address) == NODE_NETWORK_UNREACHABLE
        assert api2.get_node_network_state(
            api1.address) == NODE_NETWORK_UNREACHABLE
    assert not api1.get_channel_list(registry_address, token_address,
                                     api2.address)

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address,
                      api2.address)
    channels = api1.get_channel_list(registry_address, token_address,
                                     api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_identifier)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    event_list1 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert event_list1 == []

    token_events = api1.get_token_network_events(
        token_address,
        channel12.open_transaction.finished_block_number,
    )
    assert token_events[0]['event'] == EVENT_CHANNEL_NEW

    registry_address = api1.raiden.default_registry.address
    # Load the new state with the deposit
    api1.channel_deposit(
        registry_address,
        token_address,
        api2.address,
        deposit,
    )

    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address,
                                 api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert any(
        (event['event'] == EVENT_CHANNEL_NEW_BALANCE and is_same_address(
            event['args']['registry_address'],
            to_normalized_address(registry_address),
        ) and is_same_address(
            event['args']['participant'],
            to_normalized_address(api1.address),
        )) for event in event_list2)

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    event_list3 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert len(event_list3) > len(event_list2)
    assert any((event['event'] == EVENT_CHANNEL_CLOSED and is_same_address(
        event['args']['registry_address'],
        to_normalized_address(registry_address),
    ) and is_same_address(
        event['args']['closing_address'],
        to_normalized_address(api1.address),
    )) for event in event_list3)
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    settlement_block = (
        channel12.close_transaction.finished_block_number +
        channel12.settle_timeout +
        10  # arbitrary number of additional blocks, used to wait for the settle() call
    )
    wait_until_block(node1.raiden.chain, settlement_block)

    # Load the new state with the channel settled
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
Exemplo n.º 23
0
def test_raidenapi_channel_lifecycle(
    raiden_network: List[RaidenService],
    token_addresses,
    deposit,
    retry_timeout,
    settle_timeout_max,
):
    """Uses RaidenAPI to go through a complete channel lifecycle."""
    app1, app2 = raiden_network
    token_address = token_addresses[0]
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_raiden(app1), app1.default_registry.address,
        token_address)
    assert token_network_address

    api1 = RaidenAPI(app1)
    api2 = RaidenAPI(app2)

    registry_address = app1.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NetworkState.UNKNOWN
    assert api2.get_node_network_state(api1.address) == NetworkState.UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address,
                                     api2.address)

    # Make sure invalid arguments to get_channel_list are caught
    with pytest.raises(UnknownTokenAddress):
        api1.get_channel_list(registry_address=registry_address,
                              token_address=None,
                              partner_address=api2.address)

    address_for_lowest_settle_timeout = make_address()
    lowest_valid_settle_timeout = app1.config.reveal_timeout * 2

    # Make sure a small settle timeout is not accepted when opening a channel
    with pytest.raises(InvalidSettleTimeout):
        api1.channel_open(
            registry_address=app1.default_registry.address,
            token_address=token_address,
            partner_address=address_for_lowest_settle_timeout,
            settle_timeout=BlockTimeout(lowest_valid_settle_timeout - 1),
        )

    # Make sure the smallest settle timeout is accepted
    api1.channel_open(
        registry_address=app1.default_registry.address,
        token_address=token_address,
        partner_address=address_for_lowest_settle_timeout,
        settle_timeout=BlockTimeout(lowest_valid_settle_timeout),
    )

    address_for_highest_settle_timeout = make_address()
    highest_valid_settle_timeout = settle_timeout_max

    # Make sure a large settle timeout is not accepted when opening a channel
    with pytest.raises(InvalidSettleTimeout):
        api1.channel_open(
            registry_address=app1.default_registry.address,
            token_address=token_address,
            partner_address=address_for_highest_settle_timeout,
            settle_timeout=highest_valid_settle_timeout + 1,
        )

    # Make sure the highest settle timeout is accepted
    api1.channel_open(
        registry_address=app1.default_registry.address,
        token_address=token_address,
        partner_address=address_for_highest_settle_timeout,
        settle_timeout=highest_valid_settle_timeout,
    )

    # open is a synchronous api
    api1.channel_open(app1.default_registry.address, token_address,
                      api2.address)
    channels = api1.get_channel_list(registry_address, token_address,
                                     api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(app1, app2, token_network_address)
    assert channel.get_status(channel12) == ChannelState.STATE_OPENED

    registry_address = api1.raiden.default_registry.address
    # Check that giving a 0 total deposit is not accepted
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(
            registry_address=registry_address,
            token_address=token_address,
            partner_address=api2.address,
            total_deposit=TokenAmount(0),
        )
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=api2.address,
        total_deposit=deposit,
    )

    # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(registry_address, token_address,
                                       api2.address, deposit)

    channel12 = get_channelstate(app1, app2, token_network_address)

    assert channel.get_status(channel12) == ChannelState.STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address,
                                 api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NetworkState.REACHABLE
    assert api2.get_node_network_state(api1.address) == NetworkState.REACHABLE

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(app1, app2, token_network_address)
    assert channel.get_status(channel12) == ChannelState.STATE_CLOSED

    with pytest.raises(UnexpectedChannelState):
        api1.set_total_channel_deposit(registry_address, token_address,
                                       api2.address, deposit + 100)

    assert wait_for_state_change(
        app1,
        ContractReceiveChannelSettled,
        {
            "canonical_identifier": {
                "token_network_address": token_network_address,
                "channel_identifier": channel12.identifier,
            }
        },
        retry_timeout,
    )
Exemplo n.º 24
0
def test_channel_lifecycle(raiden_network, token_addresses, deposit):
    node1, node2 = raiden_network
    token_address = token_addresses[0]

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN
    assert not api1.get_channel_list(token_address, api2.address)

    # open is a synchronous api
    api1.channel_open(token_address, api2.address)
    channels = api1.get_channel_list(token_address, api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_address)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    event_list1 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert event_list1 == []

    # Load the new state with the deposit
    api1.channel_deposit(token_address, api2.address, deposit)
    channel12 = get_channelstate(node1, node2, token_address)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(token_address, api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert any((event['_event_type'] == b'ChannelNewBalance'
                and event['participant'] == address_encoder(api1.address))
               for event in event_list2)

    api1.channel_close(token_address, api2.address)
    node1.raiden.poll_blockchain_events()

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_address)

    event_list3 = api1.get_channel_events(
        channel12.identifier,
        channel12.open_transaction.finished_block_number,
    )
    assert len(event_list3) > len(event_list2)
    assert any((event['_event_type'] == b'ChannelClosed'
                and event['closing_address'] == address_encoder(api1.address))
               for event in event_list3)
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    settlement_block = (
        channel12.close_transaction.finished_block_number +
        channel12.settle_timeout +
        10  # arbitrary number of additional blocks, used to wait for the settle() call
    )
    wait_until_block(node1.raiden.chain, settlement_block)

    # Load the new state with the channel settled
    channel12 = get_channelstate(node1, node2, token_address)

    node1.raiden.poll_blockchain_events()
    assert channel.get_status(channel12) == CHANNEL_STATE_SETTLED
Exemplo n.º 25
0
def test_raidenapi_channel_lifecycle(raiden_network, token_addresses, deposit,
                                     retry_timeout, settle_timeout_max):
    """Uses RaidenAPI to go through a complete channel lifecycle."""
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(node1), node1.raiden.default_registry.address,
        token_address)
    assert token_network_address

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NetworkState.UNKNOWN
    assert api2.get_node_network_state(api1.address) == NetworkState.UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address,
                                     api2.address)

    # Make sure invalid arguments to get_channel_list are caught
    with pytest.raises(UnknownTokenAddress):
        api1.get_channel_list(registry_address=registry_address,
                              token_address=None,
                              partner_address=api2.address)

    address_for_lowest_settle_timeout = make_address()
    lowest_valid_settle_timeout = node1.raiden.config.reveal_timeout * 2

    # Make sure a small settle timeout is not accepted when opening a channel
    with pytest.raises(InvalidSettleTimeout):
        api1.channel_open(
            registry_address=node1.raiden.default_registry.address,
            token_address=token_address,
            partner_address=address_for_lowest_settle_timeout,
            settle_timeout=lowest_valid_settle_timeout - 1,
        )

    # Make sure the smallest settle timeout is accepted
    api1.channel_open(
        registry_address=node1.raiden.default_registry.address,
        token_address=token_address,
        partner_address=address_for_lowest_settle_timeout,
        settle_timeout=lowest_valid_settle_timeout,
    )

    address_for_highest_settle_timeout = make_address()
    highest_valid_settle_timeout = settle_timeout_max

    # Make sure a large settle timeout is not accepted when opening a channel
    with pytest.raises(InvalidSettleTimeout):
        api1.channel_open(
            registry_address=node1.raiden.default_registry.address,
            token_address=token_address,
            partner_address=address_for_highest_settle_timeout,
            settle_timeout=highest_valid_settle_timeout + 1,
        )

    # Make sure the highest settle timeout is accepted
    api1.channel_open(
        registry_address=node1.raiden.default_registry.address,
        token_address=token_address,
        partner_address=address_for_highest_settle_timeout,
        settle_timeout=highest_valid_settle_timeout,
    )

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address,
                      api2.address)
    channels = api1.get_channel_list(registry_address, token_address,
                                     api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_address)
    assert channel.get_status(channel12) == ChannelState.STATE_OPENED

    channel_event_list1 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert must_have_event(
        channel_event_list1,
        {
            "event": ChannelEvent.OPENED,
            "args": {
                "participant1": to_checksum_address(api1.address),
                "participant2": to_checksum_address(api2.address),
            },
        },
    )

    network_event_list1 = api1.get_blockchain_events_token_network(
        token_address)
    assert must_have_event(network_event_list1, {"event": ChannelEvent.OPENED})

    registry_address = api1.raiden.default_registry.address
    # Check that giving a 0 total deposit is not accepted
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(
            registry_address=registry_address,
            token_address=token_address,
            partner_address=api2.address,
            total_deposit=TokenAmount(0),
        )
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=api2.address,
        total_deposit=deposit,
    )

    # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(registry_address, token_address,
                                       api2.address, deposit)

    channel12 = get_channelstate(node1, node2, token_network_address)

    assert channel.get_status(channel12) == ChannelState.STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address,
                                 api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NetworkState.REACHABLE
    assert api2.get_node_network_state(api1.address) == NetworkState.REACHABLE

    event_list2 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert must_have_event(
        event_list2,
        {
            "event": ChannelEvent.DEPOSIT,
            "args": {
                "participant": to_checksum_address(api1.address),
                "total_deposit": deposit
            },
        },
    )

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_address)

    event_list3 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert len(event_list3) > len(event_list2)
    assert must_have_event(
        event_list3,
        {
            "event": ChannelEvent.CLOSED,
            "args": {
                "closing_participant": to_checksum_address(api1.address)
            },
        },
    )
    assert channel.get_status(channel12) == ChannelState.STATE_CLOSED

    with pytest.raises(UnexpectedChannelState):
        api1.set_total_channel_deposit(registry_address, token_address,
                                       api2.address, deposit + 100)

    assert wait_for_state_change(
        node1.raiden,
        ContractReceiveChannelSettled,
        {
            "canonical_identifier": {
                "token_network_address": token_network_address,
                "channel_identifier": channel12.identifier,
            }
        },
        retry_timeout,
    )
Exemplo n.º 26
0
 def get_balance(self, channel_state):  # pylint: disable=no-self-use
     return channel.get_balance(
         channel_state.our_state,
         channel_state.partner_state,
     )
Exemplo n.º 27
0
def run_test_raidenapi_channel_lifecycle(raiden_network, token_addresses,
                                         deposit, retry_timeout):
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(node1), node1.raiden.default_registry.address,
        token_address)

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address,
                                     api2.address)

    # Make sure invalid arguments to get_channel_list are caught
    with pytest.raises(UnknownTokenAddress):
        api1.get_channel_list(registry_address=registry_address,
                              token_address=None,
                              partner_address=api2.address)

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address,
                      api2.address)
    channels = api1.get_channel_list(registry_address, token_address,
                                     api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_identifier)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    channel_event_list1 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert must_have_event(
        channel_event_list1,
        {
            "event": ChannelEvent.OPENED,
            "args": {
                "participant1": to_checksum_address(api1.address),
                "participant2": to_checksum_address(api2.address),
            },
        },
    )

    network_event_list1 = api1.get_blockchain_events_token_network(
        token_address)
    assert must_have_event(network_event_list1, {"event": ChannelEvent.OPENED})

    registry_address = api1.raiden.default_registry.address
    # Check that giving a 0 total deposit is not accepted
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(
            registry_address=registry_address,
            token_address=token_address,
            partner_address=api2.address,
            total_deposit=0,
        )
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=api2.address,
        total_deposit=deposit,
    )

    # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(registry_address, token_address,
                                       api2.address, deposit)

    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state,
                               channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address,
                                 api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert must_have_event(
        event_list2,
        {
            "event": ChannelEvent.DEPOSIT,
            "args": {
                "participant": to_checksum_address(api1.address),
                "total_deposit": deposit
            },
        },
    )

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    event_list3 = api1.get_blockchain_events_channel(
        token_address, channel12.partner_state.address)
    assert len(event_list3) > len(event_list2)
    assert must_have_event(
        event_list3,
        {
            "event": ChannelEvent.CLOSED,
            "args": {
                "closing_participant": to_checksum_address(api1.address)
            },
        },
    )
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    assert wait_for_state_change(
        node1.raiden,
        ContractReceiveChannelSettled,
        {
            "token_network_identifier": token_network_identifier,
            "channel_identifier": channel12.identifier,
        },
        retry_timeout,
    )
Exemplo n.º 28
0
def test_channel_lifecycle(raiden_network, token_addresses, deposit, transport_protocol):
    node1, node2 = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(node1),
        node1.raiden.default_registry.address,
        token_address,
    )

    api1 = RaidenAPI(node1.raiden)
    api2 = RaidenAPI(node2.raiden)

    registry_address = node1.raiden.default_registry.address

    # nodes don't have a channel, so they are not healthchecking
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN
    assert not api1.get_channel_list(registry_address, token_address, api2.address)

    # Make sure invalid arguments to get_channel_list are caught
    with pytest.raises(UnknownTokenAddress):
        api1.get_channel_list(
            registry_address=registry_address,
            token_address=None,
            partner_address=api2.address,
        )

    # open is a synchronous api
    api1.channel_open(node1.raiden.default_registry.address, token_address, api2.address)
    channels = api1.get_channel_list(registry_address, token_address, api2.address)
    assert len(channels) == 1

    channel12 = get_channelstate(node1, node2, token_network_identifier)
    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED

    event_list1 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert any(
        (
            event['event'] == ChannelEvent.OPENED and
            is_same_address(
                event['args']['participant1'],
                to_normalized_address(api1.address),
            ) and
            is_same_address(
                event['args']['participant2'],
                to_normalized_address(api2.address),
            )
        )
        for event in event_list1
    )

    token_events = api1.get_blockchain_events_token_network(
        token_address,
    )
    assert token_events[0]['event'] == ChannelEvent.OPENED

    registry_address = api1.raiden.default_registry.address
    # Load the new state with the deposit
    api1.set_total_channel_deposit(
        registry_address,
        token_address,
        api2.address,
        deposit,
    )

    # let's make sure it's idempotent. Same deposit should raise deposit mismatch limit
    with pytest.raises(DepositMismatch):
        api1.set_total_channel_deposit(
            registry_address,
            token_address,
            api2.address,
            deposit,
        )

    channel12 = get_channelstate(node1, node2, token_network_identifier)

    assert channel.get_status(channel12) == CHANNEL_STATE_OPENED
    assert channel.get_balance(channel12.our_state, channel12.partner_state) == deposit
    assert channel12.our_state.contract_balance == deposit
    assert api1.get_channel_list(registry_address, token_address, api2.address) == [channel12]

    # there is a channel open, they must be healthchecking each other
    assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE
    assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE

    event_list2 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert any(
        (
            event['event'] == ChannelEvent.DEPOSIT and
            is_same_address(
                event['args']['participant'],
                to_normalized_address(api1.address),
            ) and
            event['args']['total_deposit'] == deposit
        )
        for event in event_list2
    )

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

    # Load the new state with the channel closed
    channel12 = get_channelstate(node1, node2, token_network_identifier)

    event_list3 = api1.get_blockchain_events_channel(
        token_address,
        channel12.partner_state.address,
    )
    assert len(event_list3) > len(event_list2)
    assert any(
        (
            event['event'] == ChannelEvent.CLOSED and
            is_same_address(
                event['args']['closing_participant'],
                to_normalized_address(api1.address),
            )
        )
        for event in event_list3
    )
    assert channel.get_status(channel12) == CHANNEL_STATE_CLOSED

    settlement_block = (
        channel12.close_transaction.finished_block_number +
        channel12.settle_timeout +
        10  # arbitrary number of additional blocks, used to wait for the settle() call
    )
    wait_until_block(node1.raiden.chain, settlement_block + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)

    state_changes = node1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(state_changes, ContractReceiveChannelSettled, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel12.identifier,
    })
Exemplo n.º 29
0
 def get_balance(channel_state: NettingChannelState) -> int:
     return channel.get_balance(channel_state.our_state,
                                channel_state.partner_state)
Exemplo n.º 30
0
def update_monitoring_service_from_balance_proof(
    raiden: "RaidenService",
    chain_state: ChainState,
    new_balance_proof: BalanceProofSignedState,
    non_closing_participant: Address,
) -> None:
    if raiden.config.services.monitoring_enabled is False:
        return

    msg = "Monitoring is enabled but the default monitoring service address is None."
    assert raiden.default_msc_address is not None, msg

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

    msg = (
        f"Failed to update monitoring service due to inability to find "
        f"channel: {new_balance_proof.channel_identifier} "
        f"token_network_address: {to_checksum_address(new_balance_proof.token_network_address)}."
    )
    assert channel_state, msg

    msg = "Monitoring is enabled but the `UserDeposit` contract is None."
    assert raiden.default_user_deposit is not None, msg
    rei_balance = raiden.default_user_deposit.effective_balance(
        raiden.address, BLOCK_ID_LATEST)
    if rei_balance < MONITORING_REWARD:
        rdn_balance = to_rdn(rei_balance)
        rdn_reward = to_rdn(MONITORING_REWARD)
        log.warning(f"Skipping update to Monitoring service. "
                    f"Your deposit balance {rdn_balance} is less than "
                    f"the required monitoring service reward of {rdn_reward}")
        return

    # In production there should be no MonitoringRequest if
    # channel balance is below a certain threshold. This is
    # a naive approach that needs to be worked on in the future
    if raiden.config.environment_type == Environment.PRODUCTION:
        message = ("Skipping update to Monitoring service. "
                   "Your channel balance {channel_balance} is less than "
                   "the required minimum balance of {min_balance} ")

        dai_token_network_address = views.get_token_network_address_by_token_address(
            chain_state=chain_state,
            token_network_registry_address=raiden.default_registry.address,
            token_address=DAI_TOKEN_ADDRESS,
        )
        weth_token_network_address = views.get_token_network_address_by_token_address(
            chain_state=chain_state,
            token_network_registry_address=raiden.default_registry.address,
            token_address=WETH_TOKEN_ADDRESS,
        )
        channel_balance = get_balance(
            sender=channel_state.our_state,
            receiver=channel_state.partner_state,
        )

        if channel_state.canonical_identifier.token_network_address == dai_token_network_address:
            if channel_balance < MIN_MONITORING_AMOUNT_DAI:
                data = dict(
                    channel_balance=channel_balance,
                    min_balance=MIN_MONITORING_AMOUNT_DAI,
                    channel_id=channel_state.canonical_identifier.
                    channel_identifier,
                    token_address=to_checksum_address(DAI_TOKEN_ADDRESS),
                )
                log.warning(message.format(**data), **data)
                return
        if channel_state.canonical_identifier.token_network_address == weth_token_network_address:
            if channel_balance < MIN_MONITORING_AMOUNT_WETH:
                data = dict(
                    channel_balance=channel_balance,
                    min_balance=MIN_MONITORING_AMOUNT_WETH,
                    channel_id=channel_state.canonical_identifier.
                    channel_identifier,
                    token_address=to_checksum_address(WETH_TOKEN_ADDRESS),
                )
                log.warning(message.format(**data), **data)
                return

    log.info(
        "Received new balance proof, creating message for Monitoring Service.",
        node=to_checksum_address(raiden.address),
        balance_proof=new_balance_proof,
    )

    monitoring_message = RequestMonitoring.from_balance_proof_signed_state(
        balance_proof=new_balance_proof,
        non_closing_participant=non_closing_participant,
        reward_amount=MONITORING_REWARD,
        monitoring_service_contract_address=raiden.default_msc_address,
    )
    monitoring_message.sign(raiden.signer)
    raiden.transport.broadcast(constants.MONITORING_BROADCASTING_ROOM,
                               monitoring_message)
Exemplo n.º 31
0
    def set_total_channel_withdraw(
        self,
        registry_address: TokenNetworkRegistryAddress,
        token_address: TokenAddress,
        partner_address: Address,
        total_withdraw: WithdrawAmount,
        retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ) -> None:
        """ Set the `total_withdraw` in the channel with the peer at `partner_address` and the
        given `token_address`.

        Raises:
            InvalidBinaryAddress: If either token_address or partner_address is not
                20 bytes long.
            RaidenUnrecoverableError: May happen for multiple reasons:
                - During preconditions checks, if the channel was not open
                  at the time of the approve_and_set_total_deposit call.
                - If the transaction fails during gas estimation or
                  if a previous withdraw transaction with the same value
                   was already mined.
            DepositMismatch: The total withdraw amount did not increase.
        """
        chain_state = views.state_from_raiden(self.raiden)

        token_addresses = views.get_token_identifiers(chain_state,
                                                      registry_address)
        channel_state = views.get_channelstate_for(
            chain_state=chain_state,
            token_network_registry_address=registry_address,
            token_address=token_address,
            partner_address=partner_address,
        )

        if not is_binary_address(token_address):
            raise InvalidBinaryAddress(
                "Expected binary address format for token in channel deposit")

        if not is_binary_address(partner_address):
            raise InvalidBinaryAddress(
                "Expected binary address format for partner in channel deposit"
            )

        if token_address not in token_addresses:
            raise UnknownTokenAddress("Unknown token address")

        if channel_state is None:
            raise NonexistingChannel(
                "No channel with partner_address for the given token")

        if total_withdraw <= channel_state.our_total_withdraw:
            raise WithdrawMismatch(
                f"Total withdraw {total_withdraw} did not increase")

        current_balance = channel.get_balance(
            sender=channel_state.our_state,
            receiver=channel_state.partner_state)
        amount_to_withdraw = total_withdraw - channel_state.our_total_withdraw
        if amount_to_withdraw > current_balance:
            raise InsufficientFunds(
                "The withdraw of {} is bigger than the current balance of {}".
                format(amount_to_withdraw, current_balance))

        self.raiden.withdraw(
            canonical_identifier=channel_state.canonical_identifier,
            total_withdraw=total_withdraw)

        waiting.wait_for_withdraw_complete(
            raiden=self.raiden,
            canonical_identifier=channel_state.canonical_identifier,
            total_withdraw=total_withdraw,
            retry_timeout=retry_timeout,
        )