def test_failsfast_lockedtransfer_exceeding_distributable(
        raiden_network,
        token_addresses,
        deposit,
):

    app0, app1 = raiden_network
    token_address = token_addresses[0]

    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )
    result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        deposit * 2,
        app1.raiden.address,
        identifier=1,
    )

    assert result.successful()
    assert result.get_nowait() is False

    assert_synced_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
Example #2
0
    def token_network_connect(
            self,
            registry_address,
            token_address,
            funds,
            initial_channel_target=3,
            joinable_funds_target=.4,
    ):
        """Automatically maintain channels open for the given token network.

        Args:
            token_address (bin): the ERC20 token network to connect to.
            funds (int): the amount of funds that can be used by the ConnectionMananger.
            initial_channel_target (int): number of channels to open proactively.
            joinable_funds_target (float): fraction of the funds that will be used to join
                channels opened by other participants.
        """
        if not is_binary_address(token_address):
            raise InvalidAddress('token_address must be a valid address in binary')

        token_network_identifier = views.get_token_network_identifier_by_token_address(
            views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        connection_manager = self.raiden.connection_manager_for_token_network(
            token_network_identifier,
        )

        connection_manager.connect(
            funds,
            initial_channel_target=initial_channel_target,
            joinable_funds_target=joinable_funds_target,
        )
def test_receive_directtransfer_invalidnonce(raiden_network, deposit, 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)

    transferred_amount = 10
    same_payment_identifier = 1
    message_identifier = random.randint(0, UINT64_MAX)

    event = channel.send_directtransfer(
        channel0,
        transferred_amount,
        message_identifier,
        same_payment_identifier,
    )

    direct_transfer_message = DirectTransfer.from_event(event)
    sign_and_inject(
        direct_transfer_message,
        app0.raiden.private_key,
        app0.raiden.address,
        app1,
    )

    # Send a *different* direct transfer with the *same nonce*
    invalid_transferred_amount = transferred_amount // 2
    message_identifier = random.randint(0, UINT64_MAX)

    invalid_direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=same_payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=invalid_transferred_amount,
        locked_amount=0,
        recipient=app1.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

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

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit - transferred_amount, [],
        app1, deposit + transferred_amount, [],
    )
Example #4
0
    def token_network_leave(
            self,
            registry_address: typing.PaymentNetworkID,
            token_address: typing.TokenAddress,
    ) -> typing.List[NettingChannelState]:
        """ Close all channels and wait for settlement. """
        if not is_binary_address(registry_address):
            raise InvalidAddress('registry_address must be a valid address in binary')
        if not is_binary_address(token_address):
            raise InvalidAddress('token_address must be a valid address in binary')

        if token_address not in self.get_tokens_list(registry_address):
            raise UnknownTokenAddress('token_address unknown')

        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        connection_manager = self.raiden.connection_manager_for_token_network(
            token_network_identifier,
        )

        return connection_manager.leave(registry_address)
Example #5
0
def test_direct_transfer(raiden_network, token_addresses, deposit, network_wait):
    token_address = token_addresses[0]
    app0, app1 = raiden_network

    amount = 10
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )
    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        timeout=network_wait,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit - amount, [],
        app1, deposit + amount, [],
    )
Example #6
0
def test_close_channel_lack_of_balance_proof(raiden_chain, deposit, token_addresses):
    app0, app1 = raiden_chain
    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,
    )

    token_proxy = app0.raiden.chain.token(token_address)
    initial_balance0 = token_proxy.balance_of(app0.raiden.address)
    initial_balance1 = token_proxy.balance_of(app1.raiden.address)

    amount = 100
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )

    # Stop app0 to avoid sending the unlock
    app0.raiden.transport.stop_and_wait()

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.on_message(app1.raiden, reveal_secret)

    RaidenAPI(app0.raiden).channel_close(
        app0.raiden.default_registry.address,
        token_address,
        app1.raiden.address,
    )

    channel_state = get_channelstate(app0, app1, token_network_identifier)
    waiting.wait_for_settle(
        app0.raiden,
        app0.raiden.default_registry.address,
        token_address,
        [channel_state.identifier],
        app0.raiden.alarm.sleep_time,
    )

    # wait for the node to call batch unlock
    with gevent.Timeout(10):
        wait_for_batch_unlock(
            app0,
            token_network_identifier,
            channel_state.partner_state.address,
            channel_state.our_state.address,
        )

    expected_balance0 = initial_balance0 + deposit - amount
    expected_balance1 = initial_balance1 + deposit + amount
    assert token_proxy.balance_of(app0.raiden.address) == expected_balance0
    assert token_proxy.balance_of(app1.raiden.address) == expected_balance1
Example #7
0
def test_regression_unfiltered_routes(
        raiden_network,
        token_addresses,
        settle_timeout,
        deposit,
):
    """ The transfer should proceed without triggering an assert.

    Transfers failed in networks where two or more paths to the destination are
    possible but they share same node as a first hop.
    """
    app0, app1, app2, app3, app4 = raiden_network
    token = token_addresses[0]
    registry_address = app0.raiden.default_registry.address

    # Topology:
    #
    #  0 -> 1 -> 2 -> 4
    #       |         ^
    #       +--> 3 ---+
    app_channels = [
        (app0, app1),
        (app1, app2),
        (app1, app3),
        (app3, app4),
        (app2, app4),
    ]

    greenlets = []
    for first_app, second_app in app_channels:
        greenlets.append(gevent.spawn(
            payment_channel_open_and_deposit,
            first_app,
            second_app,
            token,
            deposit,
            settle_timeout,
        ))
    gevent.wait(greenlets)

    wait_for_channels(
        app_channels,
        registry_address,
        [token],
        deposit,
    )

    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token,
    )
    transfer = app0.raiden.mediated_transfer_async(
        token_network_identifier=token_network_identifier,
        amount=1,
        target=app4.raiden.address,
        identifier=1,
    )
    assert transfer.wait()
def test_mediated_transfer_events(raiden_network, number_of_nodes, token_addresses, network_wait):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes,
    )

    def test_initiator_events():
        initiator_blockevents = app0.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        initiator_events = [blocknumber_event[1] for blocknumber_event in initiator_blockevents]
        return (
            must_contain_entry(initiator_events, SendRevealSecret, {}) and
            must_contain_entry(initiator_events, EventUnlockSuccess, {})
        )

    assert wait_until(test_initiator_events, network_wait)

    def test_mediator_events():
        mediator_blockevents = app1.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        mediator_events = [blocknumber_event[1] for blocknumber_event in mediator_blockevents]
        return (
            must_contain_entry(mediator_events, EventUnlockSuccess, {}) and
            must_contain_entry(mediator_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_mediator_events, network_wait)

    def test_target_events():
        target_blockevents = app2.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        target_events = [blocknumber_event[1] for blocknumber_event in target_blockevents]
        return (
            must_contain_entry(target_events, SendSecretRequest, {}) and
            must_contain_entry(target_events, SendRevealSecret, {}) and
            must_contain_entry(target_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_target_events, network_wait)
def test_refund_messages(raiden_chain, token_addresses, deposit):
    # The network has the following topology:
    #
    #   App0 <---> App1 <---> App2
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )

    # Exhaust the channel App1 <-> App2 (to force the refund transfer)
    exhaust_amount = deposit
    mediated_transfer(
        initiator_app=app1,
        target_app=app2,
        token_network_identifier=token_network_identifier,
        amount=exhaust_amount,
        identifier=1,
    )

    refund_amount = deposit // 2
    identifier = 1
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        refund_amount,
        app2.raiden.address,
        identifier,
    )
    assert async_result.wait() is False, 'Must fail, there are no routes available'

    # The transfer from app0 to app2 failed, so the balances did change.
    # Since the refund is not unlocked both channels have the corresponding
    # amount locked (issue #1091)
    send_lockedtransfer = raiden_events_must_contain_entry(
        app0.raiden,
        SendLockedTransfer,
        {'transfer': {'lock': {'amount': refund_amount}}},
    )
    assert send_lockedtransfer

    send_refundtransfer = raiden_events_must_contain_entry(app1.raiden, SendRefundTransfer, {})
    assert send_refundtransfer

    assert_synced_channel_state(
        token_network_identifier,
        app0, deposit, [send_lockedtransfer.transfer.lock],
        app1, deposit, [send_refundtransfer.transfer.lock],
    )

    # This channel was exhausted to force the refund transfer
    assert_synced_channel_state(
        token_network_identifier,
        app1, 0, [],
        app2, deposit * 2, [],
    )
Example #10
0
def test_receive_secrethashtransfer_unknown(raiden_network, token_addresses):
    app0 = raiden_network[0]
    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,
    )

    other_key = HOP1_KEY
    other_address = HOP1
    channel_identifier = make_channel_identifier()

    amount = 10
    refund_transfer_message = make_refund_transfer(
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        amount=amount,
        secrethash=UNIT_SECRETHASH,
    )
    sign_and_inject(refund_transfer_message, other_key, other_address, app0)

    secret = Secret(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        channel_identifier=channel_identifier,
        token_network_address=token_network_identifier,
        transferred_amount=amount,
        locked_amount=0,
        locksroot=UNIT_SECRETHASH,
        secret=UNIT_SECRET,
    )
    sign_and_inject(secret, other_key, other_address, app0)

    secret_request_message = SecretRequest(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        secrethash=UNIT_SECRETHASH,
        amount=1,
        expiration=refund_transfer_message.lock.expiration,
    )
    sign_and_inject(secret_request_message, other_key, other_address, app0)

    reveal_secret_message = RevealSecret(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
    )
    sign_and_inject(reveal_secret_message, other_key, other_address, app0)
Example #11
0
    def channel_batch_close(
            self,
            registry_address: typing.PaymentNetworkID,
            token_address: typing.TokenAddress,
            partner_addresses: typing.List[typing.Address],
            retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not is_binary_address(token_address):
            raise InvalidAddress('Expected binary address format for token in channel close')

        if not all(map(is_binary_address, partner_addresses)):
            raise InvalidAddress('Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        chain_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            chain_state=chain_state,
            payment_network_id=registry_address,
            token_address=token_address,
            partner_addresses=partner_addresses,
        )
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        for channel_state in channels_to_close:
            channel_close = ActionChannelClose(
                token_network_identifier=token_network_identifier,
                channel_identifier=channel_state.identifier,
            )

            self.raiden.handle_state_change(channel_close)

        channel_ids = [channel_state.identifier for channel_state in channels_to_close]

        waiting.wait_for_close(
            raiden=self.raiden,
            payment_network_id=registry_address,
            token_address=token_address,
            channel_ids=channel_ids,
            retry_timeout=retry_timeout,
        )
def test_locked_transfer_secret_registered_onchain(
        raiden_network,
        token_addresses,
        secret_registry_address,
):
    app0 = raiden_network[0]
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 1
    target = UNIT_TRANSFER_INITIATOR
    identifier = 1
    transfer_secret = sha3(target + b'1')

    secret_registry_proxy = app0.raiden.chain.secret_registry(
        secret_registry_address,
    )
    secret_registry_proxy.register_secret(transfer_secret)

    # Test that sending a transfer with a secret already registered on-chain fails
    with pytest.raises(RaidenUnrecoverableError):
        app0.raiden.start_mediated_transfer_with_secret(
            token_network_identifier,
            amount,
            target,
            identifier,
            transfer_secret,
        )

    expiration = 9999
    transfer = make_signed_transfer(
        amount,
        UNIT_TRANSFER_INITIATOR,
        app0.raiden.address,
        expiration,
        transfer_secret,
    )

    message_handler = MessageHandler()
    message_handler.handle_message_lockedtransfer(
        app0.raiden,
        transfer,
    )

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(0, 'latest')
    transfer_statechange_dispatched = (
        must_contain_entry(state_changes, ActionInitMediator, {}) or
        must_contain_entry(state_changes, ActionInitTarget, {})
    )
    assert not transfer_statechange_dispatched
Example #13
0
def test_settle_is_automatically_called(raiden_network, token_addresses, deposit):
    """Settle is automatically called by one of the nodes."""
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    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,
    )

    channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_settle(
        app0.raiden,
        registry_address,
        token_address,
        [channel_identifier],
        app0.raiden.alarm.sleep_time,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )

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

    channel_state = get_channelstate(app0, app1, token_network_identifier)
    assert channel_state.close_transaction.finished_block_number
    assert channel_state.settle_transaction.finished_block_number

    assert must_contain_entry(state_changes, ContractReceiveChannelClosed, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'closing_address': app1.raiden.address,
        'closed_block_number': channel_state.close_transaction.finished_block_number,
    })

    assert must_contain_entry(state_changes, ContractReceiveChannelSettled, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'settle_block_number': channel_state.settle_transaction.finished_block_number,
    })
def test_received_directtransfer_closedchannel(raiden_network, token_addresses, deposit):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    registry_address = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        registry_address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)

    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    wait_until_block(
        app0.raiden.chain,
        app0.raiden.chain.block_number() + 1,
    )

    # Now receive one direct transfer for the closed channel
    message_identifier = random.randint(0, UINT64_MAX)
    direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=10,
        locked_amount=0,
        recipient=app0.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

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

    # The local state must not change since the channel is already closed
    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
Example #15
0
    def transfer_async(
            self,
            registry_address: typing.PaymentNetworkID,
            token_address: typing.TokenAddress,
            amount: typing.TokenAmount,
            target: typing.Address,
            identifier: typing.PaymentID = None,
    ):

        if not isinstance(amount, int):
            raise InvalidAmount('Amount not a number')

        if amount <= 0:
            raise InvalidAmount('Amount negative')

        if not is_binary_address(token_address):
            raise InvalidAddress('token address is not valid.')

        if not is_binary_address(target):
            raise InvalidAddress('target address is not valid.')

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        log.debug(
            'Initiating transfer',
            initiator=pex(self.raiden.address),
            target=pex(target),
            token=pex(token_address),
            amount=amount,
            identifier=identifier,
        )

        payment_network_identifier = self.raiden.default_registry.address
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=payment_network_identifier,
            token_address=token_address,
        )
        async_result = self.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=target,
            identifier=identifier,
        )
        return async_result
def test_receive_lockedtransfer_invalidrecipient(
        raiden_network,
        token_addresses,
        reveal_timeout,
        deposit,
):

    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)

    payment_identifier = 1
    invalid_recipient = make_address()
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=invalid_recipient,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app1.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

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

    assert_synced_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
Example #17
0
    def token_network_connect(
            self,
            registry_address: typing.PaymentNetworkID,
            token_address: typing.TokenAddress,
            funds: typing.TokenAmount,
            initial_channel_target: int = 3,
            joinable_funds_target: float = 0.4,
    ) -> None:
        """ Automatically maintain channels open for the given token network.

        Args:
            token_address: the ERC20 token network to connect to.
            funds: the amount of funds that can be used by the ConnectionMananger.
            initial_channel_target: number of channels to open proactively.
            joinable_funds_target: fraction of the funds that will be used to join
                channels opened by other participants.
        """
        if not is_binary_address(registry_address):
            raise InvalidAddress('registry_address must be a valid address in binary')
        if not is_binary_address(token_address):
            raise InvalidAddress('token_address must be a valid address in binary')

        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        connection_manager = self.raiden.connection_manager_for_token_network(
            token_network_identifier,
        )

        has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve(
            raiden=self.raiden,
            channels_to_open=initial_channel_target,
        )

        if not has_enough_reserve:
            raise InsufficientGasReserve((
                'The account balance is below the estimated amount necessary to '
                'finish the lifecycles of all active channels. A balance of at '
                f'least {estimated_required_reserve} wei is required.'
            ))

        connection_manager.connect(
            funds=funds,
            initial_channel_target=initial_channel_target,
            joinable_funds_target=joinable_funds_target,
        )
Example #18
0
def test_automatic_secret_registration(raiden_chain, token_addresses):
    app0, app1 = raiden_chain
    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,
    )

    amount = 100
    identifier = 1

    hold_event_handler = HoldOffChainSecretRequest()
    app1.raiden.raiden_event_handler = hold_event_handler

    target = app1.raiden.address
    secret = sha3(target)
    secrethash = sha3(secret)

    hold_event_handler.hold_secretrequest_for(secrethash=secrethash)

    app0.raiden.start_mediated_transfer_with_secret(
        token_network_identifier,
        amount,
        target,
        identifier,
        secret,
    )

    gevent.sleep(1)  # wait for the messages to be exchanged

    # Stop app0 to avoid sending the unlock
    app0.raiden.transport.stop()

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.MessageHandler().on_message(app1.raiden, reveal_secret)

    chain_state = views.state_from_app(app1)

    secrethash = sha3(secret)
    target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash]
    lock_expiration = target_task.target_state.transfer.lock.expiration
    wait_until_block(app1.raiden.chain, lock_expiration)

    assert app1.raiden.default_secret_registry.check_registered(secrethash)
def test_mediated_transfer_with_entire_deposit(
        raiden_network,
        number_of_nodes,
        token_addresses,
        deposit,
        network_wait,
        public_and_private_rooms,
):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        deposit,
        timeout=network_wait * number_of_nodes,
    )

    mediated_transfer(
        app2,
        app0,
        token_network_identifier,
        deposit * 2,
        timeout=network_wait * number_of_nodes,
    )

    with gevent.Timeout(network_wait):
        wait_assert(
            assert_synced_channel_state,
            token_network_identifier,
            app0, deposit * 2, [],
            app1, 0, [],
        )
    with gevent.Timeout(network_wait):
        wait_assert(
            assert_synced_channel_state,
            token_network_identifier,
            app1, deposit * 2, [],
            app2, 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, [],
    )
def test_log_directransfer(raiden_chain, token_addresses, deposit):
    """The action that starts a direct transfer must be logged in the WAL."""
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    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,
    )

    amount = int(deposit / 2.)
    payment_identifier = 13

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        payment_identifier,
    )

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(app0_state_changes, ActionTransferDirect, {
        'token_network_identifier': token_network_identifier,
        'amount': amount,
        'receiver_address': app1.raiden.address,
    })

    app1_state_changes = app1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    assert must_contain_entry(app1_state_changes, ReceiveTransferDirect, {
        'token_network_identifier': token_network_identifier,
        'payment_identifier': payment_identifier,
        'balance_proof': {
            'transferred_amount': amount,
            'sender': app0.raiden.address,
        },
    })
Example #22
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses, transport_protocol):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token,
    )
    transfer = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

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

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(
        message_identifier,
        event.secret,
    )
    app2.raiden.sign(reveal_secret)

    if transport_protocol is TransportProtocol.UDP:
        reveal_data = reveal_secret.encode()
        host_port = None
        app1.raiden.transport.receive(reveal_data, host_port)
    elif transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError('Unknown TransportProtocol')
def test_failfast_lockedtransfer_nochannel(raiden_network, token_addresses):
    """When the node has no channels it should fail without raising exceptions."""
    token_address = token_addresses[0]
    app0, app1 = raiden_network

    amount = 10
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount,
        app1.raiden.address,
        identifier=1,
    )
    assert async_result.wait() is False
def test_mediated_transfer_messages_out_of_order(
        raiden_network,
        number_of_nodes,
        deposit,
        token_addresses,
        network_wait,
        skip_if_not_matrix,
):
    app0, app1, app2 = raiden_network
    _patch_transport(app1.raiden.transport)
    _patch_transport(app2.raiden.transport)
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes,
    )

    with gevent.Timeout(network_wait):
        wait_assert(
            assert_synced_channel_state,
            token_network_identifier,
            app0, deposit - amount, [],
            app1, deposit + amount, [],
        )
    with gevent.Timeout(network_wait):
        wait_assert(
            assert_synced_channel_state,
            token_network_identifier,
            app1, deposit - amount, [],
            app2, deposit + amount, [],
        )
Example #25
0
    def token_network_leave(self, registry_address, token_address, only_receiving=True):
        """Close all channels and wait for settlement."""
        if not is_binary_address(token_address):
            raise InvalidAddress('token_address must be a valid address in binary')

        if token_address not in self.get_tokens_list(registry_address):
            raise UnknownTokenAddress('token_address unknown')

        token_network_identifier = views.get_token_network_identifier_by_token_address(
            views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        connection_manager = self.raiden.connection_manager_for_token_network(
            token_network_identifier,
        )

        return connection_manager.leave(registry_address, only_receiving)
def test_receive_directtransfer_invalidtoken(raiden_network, deposit, 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)
    message_identifier = random.randint(0, UINT64_MAX)

    payment_identifier = 1
    invalid_token_address = make_address()
    channel_identifier = channel0.identifier
    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=invalid_token_address,
        channel_identifier=channel_identifier,
        transferred_amount=0,
        locked_amount=0,
        recipient=app1.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

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

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
Example #27
0
def transfer(initiator_app, target_app, token, amount, identifier):
    """ Nice to read shortcut to make a transfer.

    The transfer is either a DirectTransfer or a LockedTransfer, in both
    cases all apps are synched, in the case of a LockedTransfer the secret
    will be revealed.
    """
    payment_network_identifier = initiator_app.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(initiator_app),
        payment_network_identifier,
        token,
    )
    async_result = initiator_app.raiden.mediated_transfer_async(
        token_network_identifier,
        amount,
        target_app.raiden.address,
        identifier,
    )
    assert async_result.wait()
Example #28
0
def test_direct_transfer_to_offline_node(raiden_network, token_addresses, deposit):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )
    # Wait until the initialization of the node is complete and then stop it
    gevent.wait([app1.raiden.start_event])
    app1.raiden.stop()

    amount = 10
    target = app1.raiden.address
    payment_identifier = 13
    app0.raiden.direct_transfer_async(
        token_network_identifier,
        amount,
        target,
        identifier=payment_identifier,
    )

    app1.raiden.start()
    exception = ValueError('Waiting for transfer received success in the WAL timed out')
    with gevent.Timeout(seconds=5, exception=exception):
        wait_for_transfer_success(
            app1.raiden,
            payment_identifier,
            amount,
            app1.raiden.alarm.sleep_time,
        )

    no_outstanding_locks = []
    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit - amount, no_outstanding_locks,
        app1, deposit + amount, no_outstanding_locks,
    )
def test_mediated_transfer(
        raiden_network,
        number_of_nodes,
        deposit,
        token_addresses,
        network_wait,
):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes,
    )

    wait_assert(
        token_network_identifier,
        app0, deposit - amount, [],
        app1, deposit + amount, [],
        func=assert_synched_channel_state,
        timeout=network_wait,
    )
    wait_assert(
        token_network_identifier,
        app1, deposit - amount, [],
        app2, deposit + amount, [],
        func=assert_synched_channel_state,
        timeout=network_wait,
    )
def test_initiator_log_directransfer_success(raiden_chain, token_addresses, deposit):
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 7
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        identifier,
    )

    app0_events = app0.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    app0_all_events = [event for _, event in app0_events]
    assert must_contain_entry(app0_all_events, EventTransferSentSuccess, {
        'identifier': identifier,
        'amount': amount,
        'target': app1.raiden.address,
    })

    app1_state_events = app1.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    app1_all_events = [event for _, event in app1_state_events]
    assert must_contain_entry(app1_all_events, EventTransferReceivedSuccess, {
        'identifier': identifier,
        'amount': amount,
        'initiator': app0.raiden.address,
    })
Example #31
0
def _transfer_unlocked(
    initiator_app: App,
    target_app: App,
    token_address: TokenAddress,
    amount: PaymentAmount,
    identifier: PaymentID,
    fee: FeeAmount = 0,
    timeout: Optional[float] = None,
) -> None:
    assert isinstance(target_app.raiden.message_handler, WaitForMessage)

    if timeout is None:
        timeout = 10

    wait_for_unlock = target_app.raiden.message_handler.wait_for_message(
        Unlock, {"payment_identifier": identifier})

    payment_network_identifier = initiator_app.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state=views.state_from_app(initiator_app),
        payment_network_id=payment_network_identifier,
        token_address=token_address,
    )
    payment_status = initiator_app.raiden.mediated_transfer_async(
        token_network_identifier=token_network_identifier,
        amount=amount,
        target=target_app.raiden.address,
        identifier=identifier,
        fee=fee,
    )

    with Timeout(seconds=timeout):
        wait_for_unlock.get()
        msg = (f"transfer from {pex(initiator_app.raiden.address)} "
               f"to {pex(target_app.raiden.address)} failed.")
        assert payment_status.payment_done.get(), msg
Example #32
0
def handle_channel_settled(raiden, event):
    registry_address = event.event_data['registry_address']
    data = event.event_data
    channel_identifier = event.originating_contract

    channel_state = views.search_for_channel(
        views.state_from_raiden(raiden),
        registry_address,
        channel_identifier,
    )

    if channel_state:
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            views.state_from_raiden(raiden),
            registry_address,
            channel_state.token_address,
        )

        channel_settled = ContractReceiveChannelSettled(
            token_network_identifier,
            channel_identifier,
            data['block_number'],
        )
        raiden.handle_state_change(channel_settled)
Example #33
0
def _transfer_secret_not_requested(
    initiator_app: App,
    target_app: App,
    token_address: TokenAddress,
    amount: PaymentAmount,
    identifier: PaymentID,
    fee: FeeAmount = 0,
    timeout: Optional[float] = None,
):
    if timeout is None:
        timeout = 10

    secret = make_secret()
    secrethash = sha3(secret)

    hold_secret_request = target_app.raiden.raiden_event_handler.hold(
        SendSecretRequest, {"secrethash": secrethash})

    payment_network_identifier = initiator_app.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state=views.state_from_app(initiator_app),
        payment_network_id=payment_network_identifier,
        token_address=token_address,
    )
    initiator_app.raiden.start_mediated_transfer_with_secret(
        token_network_identifier=token_network_identifier,
        amount=amount,
        fee=fee,
        target=target_app.raiden.address,
        identifier=identifier,
        secret=secret,
        secrethash=secrethash,
    )

    with Timeout(seconds=timeout):
        hold_secret_request.get()
Example #34
0
def test_settled_lock(token_addresses, raiden_network, deposit):
    """ Any transfer following a secret revealed must update the locksroot, so
    hat an attacker cannot reuse a secret to double claim a lock."""
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    amount = 30
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    address0 = app0.raiden.address
    address1 = app1.raiden.address

    deposit0 = deposit
    deposit1 = deposit

    token_proxy = app0.raiden.chain.token(token_address)
    initial_balance0 = token_proxy.balance_of(address0)
    initial_balance1 = token_proxy.balance_of(address1)

    # Using a pending mediated transfer because this allows us to compute the
    # merkle proof
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_network,
        token_network_identifier,
        amount,
        identifier,
    )

    # Save the merkle tree leaves from the pending transfer, used to test the unlock
    channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier)
    batch_unlock = channel.get_batch_unlock(channelstate_0_1.our_state)
    assert batch_unlock

    claim_lock(raiden_network, identifier, token_network_identifier, secret)

    # Make a new transfer
    direct_transfer(app0, app1, token_network_identifier, amount, identifier=1)
    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_settle(
        app1.raiden,
        app1.raiden.default_registry.address,
        token_address,
        [channelstate_0_1.identifier],
        app1.raiden.alarm.sleep_time,
    )

    netting_channel = app1.raiden.chain.payment_channel(
        token_network_identifier,
        channelstate_0_1.identifier,
    )

    # The direct transfer locksroot must not contain the unlocked lock, the
    # unlock must fail.
    with pytest.raises(Exception):
        netting_channel.unlock(
            channelstate_0_1.partner_state.address,
            batch_unlock,
        )

    expected_balance0 = initial_balance0 + deposit0 - amount * 2
    expected_balance1 = initial_balance1 + deposit1 + amount * 2

    assert token_proxy.balance_of(address0) == expected_balance0
    assert token_proxy.balance_of(address1) == expected_balance1
Example #35
0
def test_refund_transfer_after_2nd_hop(
    raiden_chain,
    number_of_nodes,
    token_addresses,
    deposit,
    network_wait,
):
    """Test the refund transfer sent due to failure after 2nd hop"""
    # Topology:
    #
    #  0 -> 1 -> 2 -> 3
    #
    app0, app1, app2, app3 = raiden_chain
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )

    # make a transfer to test the path app0 -> app1 -> app2 -> app3
    identifier_path = 1
    amount_path = 1
    mediated_transfer(
        initiator_app=app0,
        target_app=app3,
        token_network_identifier=token_network_identifier,
        amount=amount_path,
        identifier=identifier_path,
        timeout=network_wait * number_of_nodes,
    )

    # drain the channel app2 -> app3
    identifier_drain = 2
    amount_drain = deposit * 8 // 10
    mediated_transfer(
        initiator_app=app2,
        target_app=app3,
        token_network_identifier=token_network_identifier,
        amount=amount_drain,
        identifier=identifier_drain,
        timeout=network_wait,
    )

    # wait for the nodes to sync
    gevent.sleep(0.2)

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [],
        app1,
        deposit + amount_path,
        [],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path,
        [],
        app2,
        deposit + amount_path,
        [],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app2,
        deposit - amount_path - amount_drain,
        [],
        app3,
        deposit + amount_path + amount_drain,
        [],
    )

    # app0 -> app1 -> app2 > app3 is the only available path, but the channel
    # app2 -> app3 doesn't have capacity, so a refund will be sent on
    # app2 -> app1 -> app0
    identifier_refund = 3
    amount_refund = 50
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount_refund,
        app3.raiden.address,
        identifier_refund,
    )
    assert async_result.wait(
    ) is False, 'there is no path with capacity, the transfer must fail'

    gevent.sleep(0.2)

    # Lock structures with the correct amount

    send_locked1 = raiden_events_search_for_item(
        app0.raiden,
        SendLockedTransfer,
        {'transfer': {
            'lock': {
                'amount': amount_refund
            }
        }},
    )
    assert send_locked1

    send_refund1 = raiden_events_search_for_item(app1.raiden,
                                                 SendRefundTransfer, {})
    assert send_refund1

    lock1 = send_locked1.transfer.lock
    refund_lock1 = send_refund1.transfer.lock
    assert lock1.amount == refund_lock1.amount
    assert lock1.secrethash == refund_lock1.secrethash

    send_locked2 = raiden_events_search_for_item(
        app1.raiden,
        SendLockedTransfer,
        {'transfer': {
            'lock': {
                'amount': amount_refund
            }
        }},
    )
    assert send_locked2

    send_refund2 = raiden_events_search_for_item(app2.raiden,
                                                 SendRefundTransfer, {})
    assert send_refund2

    lock2 = send_locked2.transfer.lock
    refund_lock2 = send_refund2.transfer.lock
    assert lock2.amount == refund_lock2.amount
    assert lock2.secrethash
    assert lock2.expiration

    # channels have the amount locked because of the refund message
    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [lockstate_from_lock(lock1)],
        app1,
        deposit + amount_path,
        [lockstate_from_lock(refund_lock1)],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path,
        [lockstate_from_lock(lock2)],
        app2,
        deposit + amount_path,
        [lockstate_from_lock(refund_lock2)],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app2,
        deposit - amount_path - amount_drain,
        [],
        app3,
        deposit + amount_path + amount_drain,
        [],
    )
Example #36
0
def test_refund_messages(raiden_chain, token_addresses, deposit):
    # The network has the following topology:
    #
    #   App0 <---> App1 <---> App2
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )

    # Exhaust the channel App1 <-> App2 (to force the refund transfer)
    exhaust_amount = deposit
    mediated_transfer(
        initiator_app=app1,
        target_app=app2,
        token_network_identifier=token_network_identifier,
        amount=exhaust_amount,
        identifier=1,
    )

    refund_amount = deposit // 2
    identifier = 1
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        refund_amount,
        app2.raiden.address,
        identifier,
    )
    assert async_result.wait(
    ) is False, 'Must fail, there are no routes available'

    # The transfer from app0 to app2 failed, so the balances did change.
    # Since the refund is not unlocked both channels have the corresponding
    # amount locked (issue #1091)
    send_lockedtransfer = raiden_events_search_for_item(
        app0.raiden,
        SendLockedTransfer,
        {'transfer': {
            'lock': {
                'amount': refund_amount
            }
        }},
    )
    assert send_lockedtransfer

    send_refundtransfer = raiden_events_search_for_item(
        app1.raiden, SendRefundTransfer, {})
    assert send_refundtransfer

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [send_lockedtransfer.transfer.lock],
        app1,
        deposit,
        [send_refundtransfer.transfer.lock],
    )

    # This channel was exhausted to force the refund transfer
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        0,
        [],
        app2,
        deposit * 2,
        [],
    )
def run_test_payment_statuses_are_restored(
    raiden_network,
    token_addresses,
    network_wait,
):
    app0, app1 = raiden_network

    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    app0.event_handler = HoldRaidenEvent()
    app0.event_handler.hold(SendSecretReveal, {})

    # make a few transfers from app0 to app1
    amount = 1
    spent_amount = 7
    identifier = 1

    for identifier in range(spent_amount):
        identifier = identifier + 1
        payment_status = app0.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=app1.raiden.address,
            identifier=identifier,
        )
        assert payment_status.payment_identifier == identifier

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        default_service_registry=app0.raiden.default_service_registry,
        transport=MatrixTransport(app0.raiden.config['transport']['matrix'], ),
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        discovery=app0.raiden.discovery,
    )
    app0.stop()
    del app0  # from here on the app0_restart should be used
    # stop app1 to make sure that we don't complete the transfers before our checks
    app1.stop()
    app0_restart.start()

    # Check that the payment statuses were restored properly after restart
    for identifier in range(spent_amount):
        identifier = identifier + 1
        mapping = app0_restart.raiden.targets_to_identifiers_to_statuses
        status = mapping[app1.raiden.address][identifier]
        assert status.amount == 1
        assert status.payment_identifier == identifier
        assert status.token_network_identifier == token_network_identifier

    app1.start()  # now that our checks are done start app1 again
    waiting.wait_for_healthy(
        app0_restart.raiden,
        app1.raiden.address,
        network_wait,
    )

    waiting.wait_for_payment_balance(
        raiden=app1.raiden,
        payment_network_id=payment_network_id,
        token_address=token_address,
        partner_address=app0_restart.raiden.address,
        target_address=app1.raiden.address,
        target_balance=spent_amount,
        retry_timeout=network_wait,
    )

    # Check that payments are completed after both nodes come online after restart
    for identifier in range(spent_amount):
        assert raiden_events_search_for_item(
            app0_restart.raiden,
            EventPaymentSentSuccess,
            {
                'identifier': identifier + 1,
                'amount': 1
            },
        )
Example #38
0
    def channel_batch_close(
        self,
        registry_address: typing.PaymentNetworkID,
        token_address: typing.TokenAddress,
        partner_addresses: typing.List[typing.Address],
        retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not is_binary_address(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel close')

        if not all(map(is_binary_address, partner_addresses)):
            raise InvalidAddress(
                'Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        chain_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            chain_state,
            registry_address,
            token_address,
            partner_addresses,
        )
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            views.state_from_raiden(self.raiden),
            registry_address,
            token_address,
        )

        # If concurrent operations are happening on one of the channels, fail entire
        # request.
        with ExitStack() as stack:
            # Put all the locks in this outer context so that the netting channel functions
            # don't release the locks when their context goes out of scope
            for channel_state in channels_to_close:
                channel = self.raiden.chain.payment_channel(
                    token_network_identifier,
                    channel_state.identifier,
                )
                stack.enter_context(channel.lock_or_raise())

            for channel_state in channels_to_close:
                channel_close = ActionChannelClose(
                    token_network_identifier,
                    channel_state.identifier,
                )

                self.raiden.handle_state_change(channel_close)

            channel_ids = [
                channel_state.identifier for channel_state in channels_to_close
            ]

            waiting.wait_for_close(
                self.raiden,
                registry_address,
                token_address,
                channel_ids,
                retry_timeout,
            )
Example #39
0
def test_receive_lockedtransfer_invalidnonce(
    raiden_network,
    deposit,
    token_addresses,
    reveal_timeout,
    network_wait,
    skip_if_not_udp,
):

    app0, app1, app2 = 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)

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait,
    )

    amount = 10
    payment_identifier = 1
    repeated_nonce = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=repeated_nonce,
        token_network_address=token_network_identifier,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=amount,
        locked_amount=amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount, expiration, UNIT_SECRETHASH),
        target=app2.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

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

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit - amount,
        [],
        app1,
        deposit + amount,
        [],
    )
Example #40
0
def test_channel_deposit(raiden_chain, deposit, retry_timeout,
                         token_addresses):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]

    registry_address = app0.raiden.default_registry.address
    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)
    channel1 = get_channelstate(app1, app0, token_network_identifier)
    assert channel0 is None
    assert channel1 is None

    RaidenAPI(app0.raiden).channel_open(registry_address, token_address,
                                        app1.raiden.address)
    gevent.sleep(retry_timeout)

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        0,
        [],
        app1,
        0,
        [],
    )

    RaidenAPI(app0.raiden).set_total_channel_deposit(
        registry_address,
        token_address,
        app1.raiden.address,
        deposit,
    )

    gevent.sleep(retry_timeout)

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        0,
        [],
    )

    RaidenAPI(app1.raiden).set_total_channel_deposit(
        registry_address,
        token_address,
        app0.raiden.address,
        deposit,
    )

    gevent.sleep(retry_timeout)

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Example #41
0
def test_recovery_happy_case(
    raiden_network,
    number_of_nodes,
    deposit,
    token_addresses,
    network_wait,
    skip_if_not_udp,
):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    # make a few transfers from app0 to app2
    amount = 1
    spent_amount = deposit - 2
    for _ in range(spent_amount):
        mediated_transfer(
            app0,
            app2,
            token_network_identifier,
            amount,
            timeout=network_wait * number_of_nodes,
        )

    app0.raiden.stop()
    host_port = (app0.raiden.config['host'], app0.raiden.config['port'])
    socket = server._udp_socket(host_port)

    new_transport = UDPTransport(
        app0.discovery,
        socket,
        app0.raiden.transport.throttle_policy,
        app0.raiden.config['transport'],
    )

    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        transport=new_transport,
        discovery=app0.raiden.discovery,
    )

    app0.stop()
    del app0  # from here on the app0_restart should be used

    assert_synched_channel_state(
        token_network_identifier,
        app0_restart,
        deposit - spent_amount,
        [],
        app1,
        deposit + spent_amount,
        [],
    )
    assert_synched_channel_state(
        token_network_identifier,
        app1,
        deposit - spent_amount,
        [],
        app2,
        deposit + spent_amount,
        [],
    )

    # wait for the nodes' healthcheck to update the network statuses
    waiting.wait_for_healthy(
        app0_restart.raiden,
        app1.raiden.address,
        network_wait,
    )
    waiting.wait_for_healthy(
        app1.raiden,
        app0_restart.raiden.address,
        network_wait,
    )

    mediated_transfer(
        app2,
        app0_restart,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes * 2,
    )
    mediated_transfer(
        app0_restart,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes * 2,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0_restart,
        deposit - spent_amount,
        [],
        app1,
        deposit + spent_amount,
        [],
    )
    assert_synched_channel_state(
        token_network_identifier,
        app1,
        deposit - spent_amount,
        [],
        app2,
        deposit + spent_amount,
        [],
    )
Example #42
0
def test_batch_unlock(raiden_network, token_addresses, secret_registry_address,
                      deposit):
    """Batch unlock can be called after the channel is settled."""
    alice_app, bob_app = raiden_network
    registry_address = alice_app.raiden.default_registry.address
    token_address = token_addresses[0]
    token_proxy = alice_app.raiden.chain.token(token_address)
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(alice_app),
        alice_app.raiden.default_registry.address,
        token_address,
    )

    token_network = views.get_token_network_by_identifier(
        views.state_from_app(alice_app),
        token_network_identifier,
    )

    channel_identifier = get_channelstate(alice_app, bob_app,
                                          token_network_identifier).identifier

    assert channel_identifier in token_network.partneraddresses_to_channels[
        bob_app.raiden.address]

    alice_initial_balance = token_proxy.balance_of(alice_app.raiden.address)
    bob_initial_balance = token_proxy.balance_of(bob_app.raiden.address)

    alice_to_bob_amount = 10
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_network,
        token_network_identifier,
        alice_to_bob_amount,
        identifier,
    )
    secrethash = sha3(secret)

    alice_bob_channel_state = get_channelstate(alice_app, bob_app,
                                               token_network_identifier)
    lock = channel.get_lock(alice_bob_channel_state.our_state, secrethash)

    # This is the current state of the protocol:
    #
    #    A -> B LockedTransfer
    #    B -> A SecretRequest
    #    - protocol didn't continue
    assert_synced_channel_state(
        token_network_identifier,
        alice_app,
        deposit,
        [lock],
        bob_app,
        deposit,
        [],
    )

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(bob_app.raiden).channel_close(
        registry_address,
        token_address,
        alice_app.raiden.address,
    )

    secret_registry_proxy = alice_app.raiden.chain.secret_registry(
        secret_registry_address, )
    secret_registry_proxy.register_secret(secret)

    assert lock, 'the lock must still be part of the node state'
    msg = 'the secret must be registered before the lock expires'
    assert lock.expiration > alice_app.raiden.get_block_number(), msg
    assert lock.secrethash == sha3(secret)

    waiting.wait_for_settle(
        alice_app.raiden,
        registry_address,
        token_address,
        [alice_bob_channel_state.identifier],
        alice_app.raiden.alarm.sleep_time,
    )

    token_network = views.get_token_network_by_identifier(
        views.state_from_app(bob_app),
        token_network_identifier,
    )

    assert channel_identifier in token_network.partneraddresses_to_channels[
        alice_app.raiden.address]

    # wait for the node to call batch unlock
    with gevent.Timeout(10):
        wait_for_batch_unlock(
            bob_app,
            token_network_identifier,
            alice_bob_channel_state.partner_state.address,
            alice_bob_channel_state.our_state.address,
        )

    token_network = views.get_token_network_by_identifier(
        views.state_from_app(bob_app),
        token_network_identifier,
    )

    assert channel_identifier not in token_network.partneraddresses_to_channels[
        alice_app.raiden.address]

    alice_new_balance = alice_initial_balance + deposit - alice_to_bob_amount
    bob_new_balance = bob_initial_balance + deposit + alice_to_bob_amount

    assert token_proxy.balance_of(
        alice_app.raiden.address) == alice_new_balance
    assert token_proxy.balance_of(bob_app.raiden.address) == bob_new_balance
Example #43
0
def test_query_events(raiden_chain, token_addresses, deposit, settle_timeout,
                      retry_timeout):
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        registry_address,
        token_address,
    )

    manager0 = app0.raiden.default_registry.token_network_by_token(
        token_address)

    channelcount0 = views.total_token_network_channels(
        views.state_from_app(app0),
        registry_address,
        token_address,
    )

    events = get_token_network_registry_events(
        app0.raiden.chain,
        registry_address,
        events=ALL_EVENTS,
    )

    assert must_have_event(
        events,
        {
            'event': EVENT_TOKEN_NETWORK_CREATED,
            'args': {
                'token_network_address': to_checksum_address(manager0.address),
                'token_address': to_checksum_address(token_address),
            },
        },
    )

    events = get_token_network_registry_events(
        app0.raiden.chain,
        app0.raiden.default_registry.address,
        events=ALL_EVENTS,
        from_block=999999998,
        to_block=999999999,
    )
    assert not events

    RaidenAPI(app0.raiden).channel_open(
        registry_address,
        token_address,
        app1.raiden.address,
    )

    events = get_token_network_events(
        app0.raiden.chain,
        manager0.address,
        events=ALL_EVENTS,
    )

    _event = must_have_event(
        events,
        {
            'event': EVENT_CHANNEL_OPENED,
            'args': {
                'participant1': to_checksum_address(app0.raiden.address),
                'participant2': to_checksum_address(app1.raiden.address),
                'settle_timeout': settle_timeout,
            },
        },
    )
    assert _event
    channel_id = _event['args']['channel_identifier']

    events = get_token_network_events(
        app0.raiden.chain,
        manager0.address,
        events=ALL_EVENTS,
        from_block=999999998,
        to_block=999999999,
    )
    assert not events

    # channel is created but not opened and without funds
    channelcount1 = views.total_token_network_channels(
        views.state_from_app(app0),
        registry_address,
        token_address,
    )
    assert channelcount0 + 1 == channelcount1

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        0,
        [],
        app1,
        0,
        [],
    )

    RaidenAPI(app0.raiden).set_total_channel_deposit(
        registry_address,
        token_address,
        app1.raiden.address,
        deposit,
    )

    all_netting_channel_events = get_all_netting_channel_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    deposit_events = get_netting_channel_deposit_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    total_deposit_event = {
        'event': EVENT_CHANNEL_DEPOSIT,
        'args': {
            'participant': to_checksum_address(app0.raiden.address),
            'total_deposit': deposit,
            'channel_identifier': channel_id,
        },
    }
    assert must_have_event(deposit_events, total_deposit_event)
    assert must_have_event(all_netting_channel_events, total_deposit_event)

    RaidenAPI(app0.raiden).channel_close(
        registry_address,
        token_address,
        app1.raiden.address,
    )

    all_netting_channel_events = get_all_netting_channel_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    closed_events = get_netting_channel_closed_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    closed_event = {
        'event': EVENT_CHANNEL_CLOSED,
        'args': {
            'channel_identifier': channel_id,
            'closing_participant': to_checksum_address(app0.raiden.address),
        },
    }
    assert must_have_event(closed_events, closed_event)
    assert must_have_event(all_netting_channel_events, closed_event)

    settle_expiration = app0.raiden.chain.block_number() + settle_timeout + 5
    wait_until_block(app0.raiden.chain, settle_expiration)

    all_netting_channel_events = get_all_netting_channel_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    settled_events = get_netting_channel_settled_events(
        app0.raiden.chain,
        token_network_identifier,
        channel_id,
    )

    settled_event = {
        'event': EVENT_CHANNEL_SETTLED,
        'args': {
            'channel_identifier': channel_id,
        },
    }
    assert must_have_event(settled_events, settled_event)
    assert must_have_event(all_netting_channel_events, settled_event)
Example #44
0
def test_lock_expiry(raiden_network, token_addresses, secret_registry_address,
                     deposit):
    """Test lock expiry and removal."""
    alice_app, bob_app = raiden_network
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(alice_app),
        alice_app.raiden.default_registry.address,
        token_address,
    )

    token_network = views.get_token_network_by_identifier(
        views.state_from_app(alice_app),
        token_network_identifier,
    )

    channel_state = get_channelstate(alice_app, bob_app,
                                     token_network_identifier)
    channel_identifier = channel_state.identifier

    assert channel_identifier in token_network.partneraddresses_to_channels[
        bob_app.raiden.address]

    alice_to_bob_amount = 10
    identifier = 1
    transfer_1_secret = pending_mediated_transfer(
        raiden_network,
        token_network_identifier,
        alice_to_bob_amount,
        identifier,
    )
    transfer_1_secrethash = sha3(transfer_1_secret)

    alice_bob_channel_state = get_channelstate(alice_app, bob_app,
                                               token_network_identifier)
    lock = channel.get_lock(alice_bob_channel_state.our_state,
                            transfer_1_secrethash)

    # This is the current state of the protocol:
    #
    #    A -> B LockedTransfer
    #    B -> A SecretRequest
    #    - protocol didn't continue
    assert_synced_channel_state(
        token_network_identifier,
        alice_app,
        deposit,
        [lock],
        bob_app,
        deposit,
        [],
    )

    # Verify lock is registered in both channel states
    alice_channel_state = get_channelstate(alice_app, bob_app,
                                           token_network_identifier)
    assert transfer_1_secrethash in alice_channel_state.our_state.secrethashes_to_lockedlocks

    bob_channel_state = get_channelstate(bob_app, alice_app,
                                         token_network_identifier)
    assert transfer_1_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks

    alice_chain_state = views.state_from_raiden(alice_app.raiden)
    assert transfer_1_secrethash in alice_chain_state.payment_mapping.secrethashes_to_task

    # Wait for the expiration to trigger with some additional buffer
    # time for processing (+2) blocks.
    waiting.wait_for_block(
        alice_app.raiden,
        lock.expiration + (DEFAULT_NUMBER_OF_CONFIRMATIONS_BLOCK + 2),
        DEFAULT_RETRY_TIMEOUT,
    )

    alice_channel_state = get_channelstate(alice_app, bob_app,
                                           token_network_identifier)
    assert transfer_1_secrethash not in alice_channel_state.our_state.secrethashes_to_lockedlocks

    # Verify Bob received the message and processed the LockExpired message
    bob_channel_state = get_channelstate(bob_app, alice_app,
                                         token_network_identifier)
    assert transfer_1_secrethash not in bob_channel_state.partner_state.secrethashes_to_lockedlocks

    alice_chain_state = views.state_from_raiden(alice_app.raiden)
    assert transfer_1_secrethash not in alice_chain_state.payment_mapping.secrethashes_to_task

    # Make another transfer
    alice_to_bob_amount = 10
    identifier = 2
    transfer_2_secret = pending_mediated_transfer(
        raiden_network,
        token_network_identifier,
        alice_to_bob_amount,
        identifier,
    )
    transfer_2_secrethash = sha3(transfer_2_secret)

    # Make sure the other transfer still exists
    alice_chain_state = views.state_from_raiden(alice_app.raiden)
    assert transfer_2_secrethash in alice_chain_state.payment_mapping.secrethashes_to_task

    bob_channel_state = get_channelstate(bob_app, alice_app,
                                         token_network_identifier)
    assert transfer_2_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks
Example #45
0
def test_unlock(raiden_network, token_addresses, deposit):
    """Unlock can be called on a closed channel."""
    alice_app, bob_app = raiden_network
    registry_address = alice_app.raiden.default_registry.address
    token_address = token_addresses[0]
    token_proxy = alice_app.raiden.chain.token(token_address)
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(alice_app),
        alice_app.raiden.default_registry.address,
        token_address,
    )

    alice_initial_balance = token_proxy.balance_of(alice_app.raiden.address)
    bob_initial_balance = token_proxy.balance_of(bob_app.raiden.address)

    alice_to_bob_amount = 10
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_network,
        token_network_identifier,
        alice_to_bob_amount,
        identifier,
    )
    secrethash = sha3(secret)

    # This is the current state of the protocol:
    #
    #    A -> B LockedTransfer
    #    B -> A SecretRequest
    #    - protocol didn't continue

    alice_bob_channel = get_channelstate(alice_app, bob_app, token_network_identifier)
    bob_alice_channel = get_channelstate(bob_app, alice_app, token_network_identifier)

    lock = channel.get_lock(alice_bob_channel.our_state, secrethash)
    assert lock

    assert_synched_channel_state(
        token_network_identifier,
        alice_app, deposit, [lock],
        bob_app, deposit, [],
    )

    # get proof, that locked transfermessage was in merkle tree, with locked.root
    unlock_proof = channel.compute_proof_for_lock(
        alice_bob_channel.our_state,
        secret,
        lock,
    )

    assert validate_proof(
        unlock_proof.merkle_proof,
        merkleroot(bob_alice_channel.partner_state.merkletree),
        sha3(lock.encoded),
    )
    assert unlock_proof.lock_encoded == lock.encoded
    assert unlock_proof.secret == secret

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(bob_app.raiden).channel_close(
        registry_address,
        token_address,
        alice_app.raiden.address,
    )

    # Unlock will not be called because the secret was not revealed
    assert lock.expiration > alice_app.raiden.chain.block_number()
    assert lock.secrethash == sha3(secret)

    nettingchannel_proxy = bob_app.raiden.chain.netting_channel(
        bob_alice_channel.identifier,
    )
    nettingchannel_proxy.unlock(unlock_proof)

    waiting.wait_for_settle(
        alice_app.raiden,
        registry_address,
        token_address,
        [alice_bob_channel.identifier],
        alice_app.raiden.alarm.wait_time,
    )

    alice_bob_channel = get_channelstate(alice_app, bob_app, token_network_identifier)
    bob_alice_channel = get_channelstate(bob_app, alice_app, token_network_identifier)

    alice_netted_balance = alice_initial_balance + deposit - alice_to_bob_amount
    bob_netted_balance = bob_initial_balance + deposit + alice_to_bob_amount

    assert token_proxy.balance_of(alice_app.raiden.address) == alice_netted_balance
    assert token_proxy.balance_of(bob_app.raiden.address) == bob_netted_balance

    # Now let's query the WAL to see if the state changes were logged as expected
    state_changes = alice_app.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    alice_bob_channel = get_channelstate(alice_app, bob_app, token_network_identifier)
    bob_alice_channel = get_channelstate(bob_app, alice_app, token_network_identifier)

    assert must_contain_entry(state_changes, ContractReceiveChannelUnlock, {
        'payment_network_identifier': registry_address,
        'token_address': token_address,
        'channel_identifier': alice_bob_channel.identifier,
        'secrethash': secrethash,
        'secret': secret,
        'receiver': bob_app.raiden.address,
    })
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 #47
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,
        })
Example #48
0
def test_secret_revealed(raiden_chain, deposit, settle_timeout,
                         token_addresses):
    app0, app1, app2 = raiden_chain
    registry_address = app0.raiden.default_registry.address
    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,
    )

    amount = 10
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )
    secrethash = sha3(secret)

    gevent.sleep(.1)  # wait for the messages

    channel_state2_1 = get_channelstate(app2, app1, token_network_identifier)

    # the secret hasn't been revealed yet (through messages)

    assert len(channel_state2_1.our_state.secrethashes_to_lockedlocks) == 1
    proofs = list(channel.get_known_unlocks(channel_state2_1.our_state))
    assert not proofs

    channel.register_secret(channel_state2_1, secret, secrethash)

    # Close the channel
    netting_channel_proxy = app2.raiden.chain.netting_channel(
        channel_state2_1.identifier)
    netting_channel_proxy.channel_close(
        registry_address,
        channel_state2_1.partner_state.balance_proof,
    )

    # Reveal the secret through the blockchain (this needs to emit the
    # SecretRevealed event)
    for unlock_proof in channel.get_known_unlocks(
            channel_state2_1.partner_state):
        netting_channel_proxy.unlock(unlock_proof)

    settle_expiration = app0.raiden.chain.block_number() + settle_timeout
    wait_until_block(app0.raiden.chain, settle_expiration)

    assert_synched_channel_state(
        token_address,
        app1,
        deposit - amount,
        [],
        app2,
        deposit + amount,
        [],
    )

    assert_synched_channel_state(
        token_address,
        app0,
        deposit - amount,
        [],
        app1,
        deposit + amount,
        [],
    )
Example #49
0
def test_secret_revealed(raiden_chain, deposit, settle_timeout,
                         token_addresses):
    app0, app1, app2 = raiden_chain
    registry_address = app0.raiden.default_registry.address
    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,
    )

    amount = 10
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )
    secrethash = sha3(secret)

    gevent.sleep(.1)  # wait for the messages

    # The secret hasn't been revealed yet
    channel_state2_1 = get_channelstate(app2, app1, token_network_identifier)
    assert len(channel_state2_1.our_state.secrethashes_to_lockedlocks) == 1

    channel.register_secret(channel_state2_1, secret, secrethash)

    # Close the channel
    # This needs to register the secrets on chain
    netting_channel_proxy = app2.raiden.chain.payment_channel(
        token_network_identifier,
        channel_state2_1.identifier,
    )
    netting_channel_proxy.channel_close(
        registry_address,
        channel_state2_1.partner_state.balance_proof,
    )

    settle_expiration = app0.raiden.chain.block_number() + settle_timeout
    wait_until_block(app0.raiden.chain, settle_expiration)

    assert_synched_channel_state(
        token_address,
        app1,
        deposit - amount,
        [],
        app2,
        deposit + amount,
        [],
    )

    assert_synched_channel_state(
        token_address,
        app0,
        deposit - amount,
        [],
        app1,
        deposit + amount,
        [],
    )
Example #50
0
def test_start_end_attack(token_addresses, raiden_chain, deposit):
    """ An attacker can try to steal tokens from a hub or the last node in a
    path.

    The attacker needs to use two addresses (A1 and A2) and connect both to the
    hub H. Once connected a mediated transfer is initialized from A1 to A2
    through H. Once the node A2 receives the mediated transfer the attacker
    uses the known secret and reveal to close and settle the channel H-A2,
    without revealing the secret to H's raiden node.

    The intention is to make the hub transfer the token but for him to be
    unable to require the token A1."""
    amount = 30

    token = token_addresses[0]
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token,
    )

    # the attacker owns app0 and app2 and creates a transfer through app1
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )
    secrethash = sha3(secret)

    attack_channel = get_channelstate(app2, app1, token_network_identifier)
    attack_transfer = None  # TODO
    attack_contract = attack_channel.external_state.netting_channel.address
    hub_contract = (get_channelstate(
        app1, app0,
        token_network_identifier).external_state.netting_channel.address)

    # the attacker can create a merkle proof of the locked transfer
    lock = attack_channel.partner_state.get_lock_by_secrethash(secrethash)
    unlock_proof = attack_channel.partner_state.compute_proof_for_lock(
        secret, lock)

    # start the settle counter
    attack_balance_proof = attack_transfer.to_balanceproof()
    attack_channel.netting_channel.channel_close(attack_balance_proof)

    # wait until the last block to reveal the secret, hopefully we are not
    # missing a block during the test
    wait_until_block(app2.raiden.chain, attack_transfer.lock.expiration - 1)

    # since the attacker knows the secret he can net the lock
    attack_channel.netting_channel.unlock(
        UnlockProofState(unlock_proof, attack_transfer.lock, secret), )
    # XXX: verify that the secret was publicized

    # at this point the hub might not know the secret yet, and won't be able to
    # claim the token from the channel A1 - H

    # the attacker settles the contract
    app2.raiden.chain.next_block()

    attack_channel.netting_channel.settle(token, attack_contract)

    # at this point the attacker has the "stolen" funds
    attack_contract = app2.raiden.chain.token_hashchannel[token][
        attack_contract]
    assert attack_contract.participants[
        app2.raiden.address]['netted'] == deposit + amount
    assert attack_contract.participants[
        app1.raiden.address]['netted'] == deposit - amount

    # and the hub's channel A1-H doesn't
    hub_contract = app1.raiden.chain.token_hashchannel[token][hub_contract]
    assert hub_contract.participants[app0.raiden.address]['netted'] == deposit
    assert hub_contract.participants[app1.raiden.address]['netted'] == deposit

    # to mitigate the attack the Hub _needs_ to use a lower expiration for the
    # locked transfer between H-A2 than A1-H. For A2 to acquire the token
    # it needs to make the secret public in the blockchain so it publishes the
    # secret through an event and the Hub is able to require its funds
    app1.raiden.chain.next_block()

    # XXX: verify that the Hub has found the secret, close and settle the channel

    # the hub has acquired its token
    hub_contract = app1.raiden.chain.token_hashchannel[token][hub_contract]
    assert hub_contract.participants[
        app0.raiden.address]['netted'] == deposit + amount
    assert hub_contract.participants[
        app1.raiden.address]['netted'] == deposit - amount
def run_test_node_can_settle_if_close_didnt_use_any_balance_proof(
    raiden_network,
    number_of_nodes,
    token_addresses,
    network_wait,
):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    registry_address = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_id,
        token_address=token_address,
    )
    channel_identifier = get_channelstate(app0, app1,
                                          token_network_identifier).identifier

    # make a transfer from app0 to app1 so that app1 is supposed to have a non
    # empty balance hash
    transfer(
        initiator_app=app0,
        target_app=app1,
        token_address=token_address,
        amount=1,
        identifier=1,
        timeout=network_wait * number_of_nodes,
    )
    # stop app1 - the test uses token_network_contract now
    app1.stop()
    token_network_contract = TokenNetwork(
        jsonrpc_client=app1.raiden.chain.client,
        token_network_address=token_network_identifier,
        contract_manager=app1.raiden.contract_manager,
    )

    # app1 closes the channel with an empty hash instead of the expected hash
    # of the transferred amount from app0
    token_network_contract.close(
        channel_identifier=channel_identifier,
        partner=app0.raiden.address,
        balance_hash=EMPTY_HASH,
        nonce=0,
        additional_hash=EMPTY_HASH,
        signature=EMPTY_SIGNATURE,
        given_block_identifier='latest',
    )
    waiting.wait_for_settle(
        raiden=app0.raiden,
        payment_network_id=registry_address,
        token_address=token_address,
        channel_ids=[channel_identifier],
        retry_timeout=app0.raiden.alarm.sleep_time,
    )
    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    assert search_for_item(
        state_changes,
        ContractReceiveChannelSettled,
        {
            'token_network_identifier': token_network_identifier,
            'channel_identifier': channel_identifier,
        },
    )
Example #52
0
def test_settle_is_automatically_called(raiden_network, token_addresses,
                                        deposit):
    """Settle is automatically called by one of the nodes."""
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    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,
    )
    token_network = views.get_token_network_by_identifier(
        views.state_from_app(app0),
        token_network_identifier,
    )

    channel_identifier = get_channelstate(app0, app1,
                                          token_network_identifier).identifier

    assert channel_identifier in token_network.partneraddresses_to_channels[
        app1.raiden.address]

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_close(
        app0.raiden,
        registry_address,
        token_address,
        [channel_identifier],
        app0.raiden.alarm.sleep_time,
    )

    channel_state = views.get_channelstate_for(
        views.state_from_raiden(app0.raiden),
        registry_address,
        token_address,
        app1.raiden.address,
    )

    assert channel_state.close_transaction.finished_block_number

    waiting.wait_for_settle(
        app0.raiden,
        registry_address,
        token_address,
        [channel_identifier],
        app0.raiden.alarm.sleep_time,
    )

    token_network = views.get_token_network_by_identifier(
        views.state_from_app(app0),
        token_network_identifier,
    )

    assert channel_identifier not in token_network.partneraddresses_to_channels[
        app1.raiden.address]

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

    assert must_contain_entry(
        state_changes, ContractReceiveChannelClosed, {
            'token_network_identifier':
            token_network_identifier,
            'channel_identifier':
            channel_identifier,
            'transaction_from':
            app1.raiden.address,
            'closed_block_number':
            channel_state.close_transaction.finished_block_number,
        })

    assert must_contain_entry(
        state_changes, ContractReceiveChannelSettled, {
            'token_network_identifier': token_network_identifier,
            'channel_identifier': channel_identifier,
        })
Example #53
0
def test_stress(
    request,
    raiden_network,
    deposit,
    retry_timeout,
    token_addresses,
    port_generator,
    skip_if_not_udp,
):

    config_converter = LogLevelConfigType()
    logging_levels = config_converter.convert(
        value=request.config.option.log_config or '',
        param=None,
        ctx=None,
    )
    _trimmed_logging(logging_levels)

    token_address = token_addresses[0]
    rest_apis = start_apiserver_for_network(raiden_network, port_generator)
    identifier_generator = count()
    timeout = 120

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(raiden_network[0]),
        raiden_network[0].raiden.default_registry.address,
        token_address,
    )

    for _ in range(3):
        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_serial_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_parallel_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_and_receive_parallel_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

    restart_network(raiden_network, retry_timeout)
Example #54
0
def test_automatic_dispute(raiden_network, deposit, token_addresses):
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    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)
    token_proxy = app0.raiden.chain.token(channel0.token_address)
    initial_balance0 = token_proxy.balance_of(app0.raiden.address)
    initial_balance1 = token_proxy.balance_of(app1.raiden.address)

    amount0_1 = 10
    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount0_1,
    )

    amount1_1 = 50
    direct_transfer(
        app1,
        app0,
        token_network_identifier,
        amount1_1,
    )

    amount0_2 = 60
    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount0_2,
    )

    # Alice can only provide one of Bob's transfer, so she is incentivized to
    # use the one with the largest transferred_amount.
    RaidenAPI(app0.raiden).channel_close(
        registry_address,
        token_address,
        app1.raiden.address,
    )

    # Bob needs to provide a transfer otherwise its netted balance will be
    # wrong, so he is incentivised to use Alice's transfer with the largest
    # transferred_amount.
    #
    # This is done automatically
    # channel1.external_state.update_transfer(
    #     alice_second_transfer,
    # )

    waiting.wait_for_settle(
        app0.raiden,
        registry_address,
        token_address,
        [channel0.identifier],
        app0.raiden.alarm.sleep_time,
    )

    # check that the channel is properly settled and that Bob's client
    # automatically called updateTransfer() to reflect the actual transactions
    assert token_proxy.balance_of(token_network_identifier) == 0
    total0 = amount0_1 + amount0_2
    total1 = amount1_1
    expected_balance0 = initial_balance0 + deposit - total0 + total1
    expected_balance1 = initial_balance1 + deposit + total0 - total1
    assert token_proxy.balance_of(app0.raiden.address) == expected_balance0
    assert token_proxy.balance_of(app1.raiden.address) == expected_balance1
Example #55
0
def test_received_lockedtransfer_closedchannel(
    raiden_network,
    reveal_timeout,
    token_addresses,
    deposit,
):

    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    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)

    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    wait_until_block(
        app0.raiden.chain,
        app0.raiden.chain.block_number() + 1,
    )

    # Now receive one mediated transfer for the closed channel
    lock_amount = 10
    payment_identifier = 1
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app1.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app1.raiden.address,
        initiator=app0.raiden.address,
        fee=0,
    )

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

    # The local state must not change since the channel is already closed
    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Example #56
0
def test_refund_transfer(raiden_chain, token_addresses, deposit, network_wait,
                         skip_if_not_udp):
    """A failed transfer must send a refund back.

    TODO:
        - Unlock the token on refund #1091
        - Clear the merkletree and update the locked amount #193
        - Remove the refund message type #490"""
    # Topology:
    #
    #  0 -> 1 -> 2
    #
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )

    # make a transfer to test the path app0 -> app1 -> app2
    identifier_path = 1
    amount_path = 1
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount_path,
        identifier_path,
        timeout=network_wait,
    )

    # drain the channel app1 -> app2
    identifier_drain = 2
    amount_drain = deposit * 8 // 10
    direct_transfer(
        app1,
        app2,
        token_network_identifier,
        amount_drain,
        identifier_drain,
        timeout=network_wait,
    )

    # wait for the nodes to sync
    gevent.sleep(0.2)

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [],
        app1,
        deposit + amount_path,
        [],
    )
    assert_synched_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )

    # app0 -> app1 -> app2 is the only available path, but the channel app1 ->
    # app2 doesn't have capacity, so a refund will be sent on app1 -> app0
    identifier_refund = 3
    amount_refund = 50
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount_refund,
        app2.raiden.address,
        identifier_refund,
    )
    assert async_result.wait(
    ) is False, 'there is no path with capacity, the transfer must fail'

    gevent.sleep(0.2)

    # A lock structure with the correct amount

    send_locked = next(
        event for _, event in app0.raiden.wal.storage.get_events_by_identifier(
            0, 'latest') if isinstance(event, SendLockedTransfer)
        and event.transfer.lock.amount == amount_refund)
    assert send_locked

    send_refund = next(
        event for _, event in app1.raiden.wal.storage.get_events_by_identifier(
            0, 'latest') if isinstance(event, SendRefundTransfer))
    assert send_refund

    lock = send_locked.transfer.lock
    refund_lock = send_refund.lock
    assert lock.amount == refund_lock.amount
    assert lock.secrethash
    assert lock.expiration

    # Both channels have the amount locked because of the refund message
    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [lockstate_from_lock(lock)],
        app1,
        deposit + amount_path,
        [lockstate_from_lock(refund_lock)],
    )
    assert_synched_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )
Example #57
0
def test_stress(
        raiden_network,
        deposit,
        retry_timeout,
        token_addresses,
        port_generator,
        skip_if_not_udp,
):
    token_address = token_addresses[0]
    rest_apis = start_apiserver_for_network(raiden_network, port_generator)
    identifier_generator = count()
    timeout = 120

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(raiden_network[0]),
        raiden_network[0].raiden.default_registry.address,
        token_address,
    )

    for _ in range(3):
        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_serial_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_parallel_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

        with gevent.Timeout(timeout):
            assert_channels(
                raiden_network,
                token_network_identifier,
                deposit,
            )

        with gevent.Timeout(timeout):
            stress_send_and_receive_parallel_transfers(
                rest_apis,
                token_address,
                identifier_generator,
                deposit,
            )

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

    restart_network(raiden_network, retry_timeout)
Example #58
0
def test_refund_transfer(
    raiden_chain,
    number_of_nodes,
    token_addresses,
    deposit,
    network_wait,
    retry_timeout,
    # UDP does not seem to retry messages until processed
    # https://github.com/raiden-network/raiden/issues/3185
    skip_if_not_matrix,
):
    """A failed transfer must send a refund back.

    TODO:
        - Unlock the token on refund #1091
        - Clear the merkletree and update the locked amount #193
        - Remove the refund message type #490"""
    # Topology:
    #
    #  0 -> 1 -> 2
    #
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )

    # make a transfer to test the path app0 -> app1 -> app2
    identifier_path = 1
    amount_path = 1
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount_path,
        identifier_path,
        timeout=network_wait * number_of_nodes,
    )

    # drain the channel app1 -> app2
    identifier_drain = 2
    amount_drain = deposit * 8 // 10
    mediated_transfer(
        initiator_app=app1,
        target_app=app2,
        token_network_identifier=token_network_identifier,
        amount=amount_drain,
        identifier=identifier_drain,
        timeout=network_wait,
    )

    # wait for the nodes to sync
    gevent.sleep(0.2)

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [],
        app1,
        deposit + amount_path,
        [],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )

    # app0 -> app1 -> app2 is the only available path, but the channel app1 ->
    # app2 doesn't have capacity, so a refund will be sent on app1 -> app0
    identifier_refund = 3
    amount_refund = 50
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount_refund,
        app2.raiden.address,
        identifier_refund,
    )
    assert async_result.wait(
    ) is False, 'there is no path with capacity, the transfer must fail'

    gevent.sleep(0.2)

    # A lock structure with the correct amount

    send_locked = raiden_events_search_for_item(
        app0.raiden,
        SendLockedTransfer,
        {'transfer': {
            'lock': {
                'amount': amount_refund
            }
        }},
    )
    assert send_locked
    secrethash = send_locked.transfer.lock.secrethash

    send_refund = raiden_events_search_for_item(app1.raiden,
                                                SendRefundTransfer, {})
    assert send_refund

    lock = send_locked.transfer.lock
    refund_lock = send_refund.transfer.lock
    assert lock.amount == refund_lock.amount
    assert lock.secrethash
    assert lock.expiration
    assert lock.secrethash == refund_lock.secrethash

    # Both channels have the amount locked because of the refund message
    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [lockstate_from_lock(lock)],
        app1,
        deposit + amount_path,
        [lockstate_from_lock(refund_lock)],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )

    # Additional checks for LockExpired causing nonce mismatch after refund transfer:
    # https://github.com/raiden-network/raiden/issues/3146#issuecomment-447378046
    # At this point make sure that the initiator has not deleted the payment task
    assert secrethash in state_from_raiden(
        app0.raiden).payment_mapping.secrethashes_to_task

    # Wait for lock lock expiration but make sure app0 never processes LockExpired
    with dont_handle_lock_expired_mock(app0):
        wait_for_block(
            raiden=app0.raiden,
            block_number=channel.get_sender_expiration_threshold(lock) + 1,
            retry_timeout=retry_timeout,
        )
        # make sure that app0 still has the payment task for the secrethash
        # https://github.com/raiden-network/raiden/issues/3183
        assert secrethash in state_from_raiden(
            app0.raiden).payment_mapping.secrethashes_to_task

        # make sure that app1 sent a lock expired message for the secrethash
        send_lock_expired = raiden_events_search_for_item(
            app1.raiden,
            SendLockExpired,
            {'secrethash': secrethash},
        )
        assert send_lock_expired
        # make sure that app0 never got it
        state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
            0, 'latest')
        assert not search_for_item(
            state_changes,
            ReceiveLockExpired,
            {'secrethash': secrethash},
        )

    # Out of the handicapped app0 transport.
    # Now wait till app0 receives and processes LockExpired
    receive_lock_expired = wait_for_state_change(
        app0.raiden,
        ReceiveLockExpired,
        {'secrethash': secrethash},
        retry_timeout,
    )
    # And also till app1 received the processed
    wait_for_state_change(
        app1.raiden,
        ReceiveProcessed,
        {'message_identifier': receive_lock_expired.message_identifier},
        retry_timeout,
    )

    # make sure app1 queue has cleared the SendLockExpired
    chain_state1 = views.state_from_app(app1)
    queues1 = views.get_all_messagequeues(chain_state=chain_state1)
    result = [(queue_id, queue) for queue_id, queue in queues1.items()
              if queue_id.recipient == app0.raiden.address and queue]
    assert not result

    # and now wait for 1 more block so that the payment task can be deleted
    wait_for_block(
        raiden=app0.raiden,
        block_number=app0.raiden.get_block_number() + 1,
        retry_timeout=retry_timeout,
    )

    # and since the lock expired message has been sent and processed then the
    # payment task should have been deleted from both nodes
    # https://github.com/raiden-network/raiden/issues/3183
    assert secrethash not in state_from_raiden(
        app0.raiden).payment_mapping.secrethashes_to_task
    assert secrethash not in state_from_raiden(
        app1.raiden).payment_mapping.secrethashes_to_task
def run_test_send_queued_messages(
    raiden_network,
    deposit,
    token_addresses,
    network_wait,
):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    with dont_handle_node_change_network_state():
        # stop app1 - transfer must be left unconfirmed
        app1.stop()

        # make a few transfers from app0 to app1
        amount = 1
        spent_amount = 7
        identifier = 1
        for _ in range(spent_amount):
            app0.raiden.mediated_transfer_async(
                token_network_identifier=token_network_identifier,
                amount=amount,
                target=app1.raiden.address,
                identifier=identifier,
            )
            identifier += 1

    # restart app0
    app0.raiden.stop()

    new_transport = MatrixTransport(
        app0.raiden.config['transport']['matrix'], )

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        default_service_registry=app0.raiden.default_service_registry,
        transport=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        discovery=app0.raiden.discovery,
    )

    app0.stop()
    del app0  # from here on the app0_restart should be used
    app1.start()

    app0_restart.start()

    waiting.wait_for_healthy(
        app0_restart.raiden,
        app1.raiden.address,
        network_wait,
    )
    waiting.wait_for_healthy(
        app1.raiden,
        app0_restart.raiden.address,
        network_wait,
    )

    exception = RuntimeError('Timeout while waiting for new channel')
    with gevent.Timeout(5, exception=exception):
        waiting.wait_for_newchannel(
            raiden=app0_restart.raiden,
            payment_network_id=payment_network_id,
            token_address=token_address,
            partner_address=app1.raiden.address,
            retry_timeout=network_wait,
        )
    exception = RuntimeError(
        'Timeout while waiting for balance update for app0')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_payment_balance(
            raiden=app0_restart.raiden,
            payment_network_id=payment_network_id,
            token_address=token_address,
            partner_address=app1.raiden.address,
            target_address=app1.raiden.address,
            target_balance=spent_amount,
            retry_timeout=network_wait,
        )

    waiting.wait_for_payment_balance(
        raiden=app1.raiden,
        payment_network_id=payment_network_id,
        token_address=token_address,
        partner_address=app0_restart.raiden.address,
        target_address=app1.raiden.address,
        target_balance=spent_amount,
        retry_timeout=network_wait,
    )

    assert_synced_channel_state(
        token_network_identifier,
        app0_restart,
        deposit - spent_amount,
        [],
        app1,
        deposit + spent_amount,
        [],
    )
Example #60
0
def test_different_view_of_last_bp_during_unlock(
    raiden_chain,
    number_of_nodes,
    token_addresses,
    deposit,
    network_wait,
    retry_timeout,
    # UDP does not seem to retry messages until processed
    # https://github.com/raiden-network/raiden/issues/3185
    skip_if_not_matrix,
):
    """Test for https://github.com/raiden-network/raiden/issues/3196#issuecomment-449163888"""
    # Topology:
    #
    #  0 -> 1 -> 2
    #
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token_address,
    )
    token_proxy = app0.raiden.chain.token(token_address)
    initial_balance0 = token_proxy.balance_of(app0.raiden.address)
    initial_balance1 = token_proxy.balance_of(app1.raiden.address)

    # make a transfer to test the path app0 -> app1 -> app2
    identifier_path = 1
    amount_path = 1
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount_path,
        identifier_path,
        timeout=network_wait * number_of_nodes,
    )

    # drain the channel app1 -> app2
    identifier_drain = 2
    amount_drain = deposit * 8 // 10
    mediated_transfer(
        initiator_app=app1,
        target_app=app2,
        token_network_identifier=token_network_identifier,
        amount=amount_drain,
        identifier=identifier_drain,
        timeout=network_wait,
    )

    # wait for the nodes to sync
    gevent.sleep(0.2)

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [],
        app1,
        deposit + amount_path,
        [],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )

    # app0 -> app1 -> app2 is the only available path, but the channel app1 ->
    # app2 doesn't have capacity, so a refund will be sent on app1 -> app0
    identifier_refund = 3
    amount_refund = 50
    async_result = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount_refund,
        app2.raiden.address,
        identifier_refund,
    )
    assert async_result.wait(
    ) is False, 'there is no path with capacity, the transfer must fail'

    gevent.sleep(0.2)

    # A lock structure with the correct amount

    send_locked = raiden_events_search_for_item(
        app0.raiden,
        SendLockedTransfer,
        {'transfer': {
            'lock': {
                'amount': amount_refund
            }
        }},
    )
    assert send_locked
    secrethash = send_locked.transfer.lock.secrethash

    send_refund = raiden_events_search_for_item(app1.raiden,
                                                SendRefundTransfer, {})
    assert send_refund

    lock = send_locked.transfer.lock
    refund_lock = send_refund.transfer.lock
    assert lock.amount == refund_lock.amount
    assert lock.secrethash
    assert lock.expiration
    assert lock.secrethash == refund_lock.secrethash

    # Both channels have the amount locked because of the refund message
    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit - amount_path,
        [lockstate_from_lock(lock)],
        app1,
        deposit + amount_path,
        [lockstate_from_lock(refund_lock)],
    )
    assert_synced_channel_state(
        token_network_identifier,
        app1,
        deposit - amount_path - amount_drain,
        [],
        app2,
        deposit + amount_path + amount_drain,
        [],
    )

    # Additional checks for LockExpired causing nonce mismatch after refund transfer:
    # https://github.com/raiden-network/raiden/issues/3146#issuecomment-447378046
    # At this point make sure that the initiator has not deleted the payment task
    assert secrethash in state_from_raiden(
        app0.raiden).payment_mapping.secrethashes_to_task

    with dont_handle_node_change_network_state():
        # now app1 goes offline
        app1.raiden.stop()
        app1.raiden.get()
        assert not app1.raiden

        # Wait for lock expiration so that app0 sends a LockExpired
        wait_for_block(
            raiden=app0.raiden,
            block_number=channel.get_sender_expiration_threshold(lock) + 1,
            retry_timeout=retry_timeout,
        )

        # make sure that app0 sent a lock expired message for the secrethash
        wait_for_raiden_event(
            app0.raiden,
            SendLockExpired,
            {'secrethash': secrethash},
            retry_timeout,
        )

        # now app0 closes the channel
        RaidenAPI(app0.raiden).channel_close(
            registry_address=payment_network_identifier,
            token_address=token_address,
            partner_address=app1.raiden.address,
        )

    count = 0
    original_update = app1.raiden.raiden_event_handler.handle_contract_send_channelupdate

    def patched_update(raiden, event):
        nonlocal count
        count += 1
        original_update(raiden, event)

    app1.raiden.raiden_event_handler.handle_contract_send_channelupdate = patched_update
    # and now app1 comes back online
    app1.raiden.start()
    # test for https://github.com/raiden-network/raiden/issues/3216
    assert count == 1, 'Update transfer should have only been called once during restart'
    channel_identifier = get_channelstate(app0, app1,
                                          token_network_identifier).identifier

    # and we wait for settlement
    wait_for_settle(
        raiden=app0.raiden,
        payment_network_id=payment_network_identifier,
        token_address=token_address,
        channel_ids=[channel_identifier],
        retry_timeout=app0.raiden.alarm.sleep_time,
    )

    with gevent.Timeout(10):
        unlock_app0 = wait_for_state_change(
            app0.raiden,
            ContractReceiveChannelBatchUnlock,
            {'participant': app0.raiden.address},
            retry_timeout,
        )
    assert unlock_app0.returned_tokens == 50
    with gevent.Timeout(10):
        unlock_app1 = wait_for_state_change(
            app1.raiden,
            ContractReceiveChannelBatchUnlock,
            {'participant': app1.raiden.address},
            retry_timeout,
        )
    assert unlock_app1.returned_tokens == 50
    final_balance0 = token_proxy.balance_of(app0.raiden.address)
    final_balance1 = token_proxy.balance_of(app1.raiden.address)

    assert final_balance0 - deposit - initial_balance0 == -1
    assert final_balance1 - deposit - initial_balance1 == 1