Example #1
0
    def patch_channel(self, channel_address, balance=None, state=None):
        if balance is not None and state is not None:
            return make_response(
                'Can not update balance and change channel state at the same time',
                httplib.CONFLICT,
            )
        elif balance is None and state is None:
            return make_response(
                'Nothing to do. Should either provide \'balance\' or \'state\' argument',
                httplib.BAD_REQUEST,
            )

        # find the channel
        channel = self.raiden_api.get_channel(channel_address)
        current_state = channel.state

        # if we patch with `balance` it's a deposit
        if balance is not None:
            if current_state != CHANNEL_STATE_OPENED:
                return make_response(
                    "Can't deposit on a closed channel",
                    httplib.CONFLICT,
                )
            raiden_service_result = self.raiden_api.deposit(
                channel.token_address, channel.partner_address, balance)
            result = self.channel_schema.dump(
                channel_to_api_dict(raiden_service_result))
            return jsonify(result.data)

        if state == CHANNEL_STATE_CLOSED:
            if current_state != CHANNEL_STATE_OPENED:
                return make_response(
                    httplib.CONFLICT,
                    'Attempted to close an already closed channel')
            raiden_service_result = self.raiden_api.close(
                channel.token_address, channel.partner_address)
            result = self.channel_schema.dump(
                channel_to_api_dict(raiden_service_result))
            return jsonify(result.data)

        if state == CHANNEL_STATE_SETTLED:
            if current_state == CHANNEL_STATE_SETTLED or current_state == CHANNEL_STATE_OPENED:
                return make_response(
                    'Attempted to settle a channel at its {} state'.format(
                        current_state),
                    httplib.CONFLICT,
                )
            raiden_service_result = self.raiden_api.settle(
                channel.token_address, channel.partner_address)
            result = self.channel_schema.dump(
                channel_to_api_dict(raiden_service_result))
            return jsonify(result.data)

        # should never happen, channel_state is validated in the schema
        return make_response(
            'Provided invalid channel state {}'.format(state),
            httplib.BAD_REQUEST,
        )
Example #2
0
    def open(self,
             partner_address,
             token_address,
             settle_timeout=None,
             reveal_timeout=None,
             balance=None):
        try:
            raiden_service_result = self.raiden_api.open(
                token_address,
                partner_address,
                settle_timeout,
                reveal_timeout,
            )
        except (InvalidAddress, InvalidSettleTimeout, SamePeerAddress,
                AddressWithoutCode, NoTokenManager,
                DuplicatedChannelError) as e:
            return api_error(errors=str(e), status_code=HTTPStatus.CONFLICT)

        if balance:
            # make initial deposit
            try:
                raiden_service_result = self.raiden_api.deposit(
                    token_address, partner_address, balance)
            except EthNodeCommunicationError as e:
                return api_error(errors=str(e),
                                 status_code=HTTPStatus.REQUEST_TIMEOUT)
            except InsufficientFunds as e:
                return api_error(errors=str(e),
                                 status_code=HTTPStatus.PAYMENT_REQUIRED)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data, status_code=HTTPStatus.CREATED)
Example #3
0
    def open(self,
             token_address,
             partner_address,
             settle_timeout=None,
             reveal_timeout=None):
        """ Open a channel with the peer at `partner_address`
        with the given `token_address`.
        """
        if reveal_timeout is None:
            reveal_timeout = self.raiden.config['reveal_timeout']

        if settle_timeout is None:
            settle_timeout = self.raiden.config['settle_timeout']

        if settle_timeout < self.raiden.config['settle_timeout']:
            raise ValueError(
                'Configured minimum `settle_timeout` is {} blocks.'.format(
                    self.raiden.config['settle_timeout']))

        channel_manager = self.raiden.chain.manager_by_token(
            token_address.decode('hex'))
        token_manager = self.raiden.get_manager_by_token_address(
            token_address.decode('hex'))
        netcontract_address = channel_manager.new_netting_channel(
            self.raiden.address,
            partner_address.decode('hex'),
            settle_timeout,
        )
        netting_channel = self.raiden.chain.netting_channel(
            netcontract_address)
        token_manager.register_channel(netting_channel, reveal_timeout)

        channel = token_manager.get_channel_by_contract_address(
            netcontract_address)
        return channel_to_api_dict(channel)
Example #4
0
    def open(self, partner_address, token_address, settle_timeout, balance=None):
        try:
            raiden_service_result = self.raiden_api.open(
                token_address,
                partner_address,
                settle_timeout
            )
        except (InvalidAddress, InvalidSettleTimeout, SamePeerAddress) as e:
            return make_response(str(e), httplib.CONFLICT)

        if balance:
            # make initial deposit
            try:
                raiden_service_result = self.raiden_api.deposit(
                    token_address,
                    partner_address,
                    balance
                )
            except EthNodeCommunicationError as e:
                return make_response(str(e), httplib.REQUEST_TIMEOUT)
            except InsufficientFunds as e:
                return make_response(str(e), httplib.PAYMENT_REQUIRED)

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return jsonify_with_response(data=result.data, status_code=httplib.CREATED)
Example #5
0
    def settle(self, token_address, partner_address):
        """ Settle a closed channel with `partner_address` for the given `token_address`. """
        token_address_bin = safe_address_decode(token_address)
        partner_address_bin = safe_address_decode(partner_address)

        if not isaddress(
                token_address_bin) or token_address_bin not in self.tokens:
            raise InvalidAddress('token address is not valid.')

        if not isaddress(partner_address_bin):
            raise InvalidAddress('partner_address is not valid.')

        manager = self.raiden.get_manager_by_token_address(token_address_bin)
        channel = manager.get_channel_by_partner_address(partner_address_bin)

        if channel.isopen:
            raise InvalidState('channel is still open.')

        netting_channel = channel.external_state.netting_channel

        if (self.raiden.chain.block_number() <=
            (channel.external_state.closed_block +
             netting_channel.detail(self.raiden.address)['settle_timeout'])):
            raise InvalidState('settlement period is not yet over.')

        netting_channel.settle()
        return channel_to_api_dict(channel)
Example #6
0
    def close(self, token_address, partner_address):
        """ Close a channel opened with `partner_address` for the given `token_address`. """
        token_address_bin = safe_address_decode(token_address)
        partner_address_bin = safe_address_decode(partner_address)

        if not isaddress(
                token_address_bin) or token_address_bin not in self.tokens:
            raise InvalidAddress('token address is not valid.')

        if not isaddress(partner_address_bin):
            raise InvalidAddress('partner_address is not valid.')

        manager = self.raiden.get_manager_by_token_address(token_address_bin)
        channel = manager.get_channel_by_partner_address(partner_address_bin)

        first_transfer = None
        if channel.received_transfers:
            first_transfer = channel.received_transfers[-1]

        netting_channel = channel.external_state.netting_channel
        netting_channel.close(
            self.raiden.address,
            first_transfer,
        )

        return channel_to_api_dict(channel)
Example #7
0
    def deposit(self, token_address, partner_address, amount):
        """ Deposit `amount` in the channel with the peer at `partner_address` and the
        given `token_address` in order to be able to do transfers.
        """
        token_manager = self.raiden.get_manager_by_token_address(
            token_address.decode('hex'))
        channel = token_manager.get_channel_by_partner_address(
            partner_address.decode('hex'))
        netcontract_address = channel.channel_address
        assert len(netcontract_address)

        # Obtain a reference to the token and approve the amount for funding
        token = self.raiden.chain.token(token_address.decode('hex'))
        balance = token.balance_of(self.raiden.address.encode('hex'))

        if not balance >= amount:
            msg = "Not enough balance for token'{}' [{}]: have={}, need={}".format(
                token.proxy.name(), token_address, balance, amount)
            raise InsufficientFunds(msg)

        token.approve(netcontract_address, amount)

        # Obtain the netting channel and fund it by depositing the amount
        netting_channel = self.raiden.chain.netting_channel(
            netcontract_address)
        netting_channel.deposit(self.raiden.address, amount)

        return channel_to_api_dict(channel)
Example #8
0
    def deposit(self, token_address, partner_address, amount):

        raiden_service_result = self.raiden_api.deposit(
            token_address, partner_address, amount)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return jsonify(result.data)
Example #9
0
    def close(self, token_address, partner_address):

        raiden_service_result = self.raiden_api.close(token_address,
                                                      partner_address)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return jsonify(result.data)
Example #10
0
    def close(self, token_address, partner_address):

        raiden_service_result = self.raiden_api.close(
            token_address,
            partner_address
        )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #11
0
def test_channel_to_api_dict():
    channel_address = b'\x00' * 20
    token_address = b'\x01' * 20
    our_address = b'\x02' * 20
    partner_address = b'\x03' * 20

    reveal_timeout = 10
    settle_timeout = 50
    opened_block = 900
    our_balance = 13
    partner_balance = 21

    our_state = ChannelEndState(
        our_address,
        our_balance,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        partner_address,
        partner_balance,
        None,
        EMPTY_MERKLE_TREE,
    )

    # mock external state to provide the channel address
    class NettingChannel(object):
        address = channel_address

    class ExternalState(object):
        def __init__(self, opened_block):
            self.netting_channel = NettingChannel()
            self.settled_block = 0
            self.closed_block = 0
            self.opened_block = opened_block

    channel = Channel(
        our_state,
        partner_state,
        ExternalState(opened_block),
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    result = channel_to_api_dict(channel)
    expected_result = {
        'channel_address': channel_address,
        'token_address': token_address,
        'partner_address': partner_address,
        'settle_timeout': settle_timeout,
        'reveal_timeout': reveal_timeout,
        'balance': our_balance,
        'state': CHANNEL_STATE_OPENED
    }
    assert result == expected_result
def test_channel_to_api_dict():
    channel_address = b'\x00' * 20
    token_address = b'\x01' * 20
    our_address = b'\x02' * 20
    partner_address = b'\x03' * 20

    reveal_timeout = 10
    settle_timeout = 50
    opened_block = 900
    our_balance = 13
    partner_balance = 21

    our_state = ChannelEndState(
        our_address,
        our_balance,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        partner_address,
        partner_balance,
        None,
        EMPTY_MERKLE_TREE,
    )

    # mock external state to provide the channel address
    class NettingChannel:
        address = channel_address

    class ExternalState:
        def __init__(self, opened_block):
            self.netting_channel = NettingChannel()
            self.settled_block = 0
            self.closed_block = 0
            self.opened_block = opened_block

    channel = Channel(
        our_state,
        partner_state,
        ExternalState(opened_block),
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    result = channel_to_api_dict(channel)
    expected_result = {
        'channel_address': channel_address,
        'token_address': token_address,
        'partner_address': partner_address,
        'settle_timeout': settle_timeout,
        'reveal_timeout': reveal_timeout,
        'balance': our_balance,
        'state': CHANNEL_STATE_OPENED
    }
    assert result == expected_result
Example #13
0
    def deposit(self, token_address, partner_address, amount):

        try:
            raiden_service_result = self.raiden_api.deposit(
                token_address, partner_address, amount)
        except EthNodeCommunicationError as e:
            return make_response(str(e), httplib.REQUEST_TIMEOUT)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return jsonify(result.data)
Example #14
0
    def _close(self, channel):
        if channel.state != CHANNEL_STATE_OPENED:
            return api_error(
                errors='Attempted to close an already closed channel',
                status_code=HTTPStatus.CONFLICT,
            )

        raiden_service_result = self.raiden_api.close(channel.token_address,
                                                      channel.partner_address)
        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #15
0
    def _close(self, channel):
        if channel.state != CHANNEL_STATE_OPENED:
            return api_error(
                errors='Attempted to close an already closed channel',
                status_code=HTTPStatus.CONFLICT,
            )

        raiden_service_result = self.raiden_api.close(
            channel.token_address,
            channel.partner_address
        )
        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #16
0
    def deposit(self, token_address, partner_address, amount):
        try:
            raiden_service_result = self.raiden_api.deposit(
                token_address, partner_address, amount)
        except EthNodeCommunicationError as e:
            return api_error(errors=str(e),
                             status_code=HTTPStatus.REQUEST_TIMEOUT)
        except InsufficientFunds as e:
            return api_error(errors=str(e),
                             status_code=HTTPStatus.PAYMENT_REQUIRED)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #17
0
def test_channel_to_api_dict(raiden_network, tokens_addresses, settle_timeout):
    app0, app1 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking
    channel0 = channel(app0, app1, tokens_addresses[0])

    netting_address = channel0.external_state.netting_channel.address
    netting_channel = app0.raiden.chain.netting_channel(netting_address)

    result = channel_to_api_dict(channel0)
    expected_result = {
        "channel_address": bytes_to_hexstr(netting_channel.address),
        "token_address": bytes_to_hexstr(channel0.token_address),
        "partner_address": bytes_to_hexstr(app1.raiden.address),
        "settle_timeout": settle_timeout,
        "balance": channel0.contract_balance,
        "state": "open"
    }
    assert result == expected_result
Example #18
0
    def open(self,
             partner_address,
             token_address,
             settle_timeout,
             balance=None):
        raiden_service_result = self.raiden_api.open(token_address,
                                                     partner_address,
                                                     settle_timeout)

        if balance:
            # make initial deposit
            raiden_service_result = self.raiden_api.deposit(
                token_address, partner_address, balance)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return jsonify(result.data)
Example #19
0
def test_channel_to_api_dict(raiden_network, token_addresses, settle_timeout):
    app0, app1 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking
    channel0 = channel(app0, app1, token_addresses[0])

    netting_address = channel0.external_state.netting_channel.address
    netting_channel = app0.raiden.chain.netting_channel(netting_address)

    result = channel_to_api_dict(channel0)
    expected_result = {
        'channel_address': netting_channel.address,
        'token_address': channel0.token_address,
        'partner_address': app1.raiden.address,
        'settle_timeout': settle_timeout,
        'balance': channel0.contract_balance,
        'state': CHANNEL_STATE_OPENED
    }
    assert result == expected_result
Example #20
0
    def _deposit(self, channel, balance):
        if channel.state != CHANNEL_STATE_OPENED:
            return api_error(
                errors="Can't deposit on a closed channel",
                status_code=HTTPStatus.CONFLICT,
            )

        try:
            raiden_service_result = self.raiden_api.deposit(
                channel.token_address, channel.partner_address, balance)
        except InsufficientFunds as e:
            return api_error(errors=str(e),
                             status_code=HTTPStatus.PAYMENT_REQUIRED)

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #21
0
    def open(
            self,
            partner_address,
            token_address,
            settle_timeout=None,
            reveal_timeout=None,
            balance=None):
        try:
            raiden_service_result = self.raiden_api.open(
                token_address,
                partner_address,
                settle_timeout,
                reveal_timeout,
            )
        except (InvalidAddress, InvalidSettleTimeout, SamePeerAddress,
                AddressWithoutCode, NoTokenManager, DuplicatedChannelError) as e:
            return api_error(
                errors=str(e),
                status_code=HTTPStatus.CONFLICT
            )

        if balance:
            # make initial deposit
            try:
                raiden_service_result = self.raiden_api.deposit(
                    token_address,
                    partner_address,
                    balance
                )
            except EthNodeCommunicationError as e:
                return api_error(
                    errors=str(e),
                    status_code=HTTPStatus.REQUEST_TIMEOUT
                )
            except InsufficientFunds as e:
                return api_error(
                    errors=str(e),
                    status_code=HTTPStatus.PAYMENT_REQUIRED
                )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(
            result=result.data,
            status_code=HTTPStatus.CREATED
        )
Example #22
0
    def _settle(self, channel):
        if channel.state != CHANNEL_STATE_CLOSED:
            return api_error(
                errors='Attempted to settle a channel at its {} state'.format(
                    channel.state, ),
                status_code=HTTPStatus.CONFLICT,
            )

        try:
            raiden_service_result = self.raiden_api.settle(
                channel.token_address, channel.partner_address)
        except InvalidState:
            return api_error(
                errors='Settlement period is not yet over',
                status_code=HTTPStatus.CONFLICT,
            )

        result = self.channel_schema.dump(
            channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #23
0
    def deposit(self, token_address, partner_address, amount):
        try:
            raiden_service_result = self.raiden_api.deposit(
                token_address,
                partner_address,
                amount
            )
        except EthNodeCommunicationError as e:
            return api_error(
                errors=str(e),
                status_code=HTTPStatus.REQUEST_TIMEOUT
            )
        except InsufficientFunds as e:
            return api_error(
                errors=str(e),
                status_code=HTTPStatus.PAYMENT_REQUIRED
            )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #24
0
    def open(self, partner_address, token_address, settle_timeout, balance=None):
        try:
            raiden_service_result = self.raiden_api.open(
                token_address,
                partner_address,
                settle_timeout
            )
        except (InvalidAddress, InvalidSettleTimeout) as e:
            return make_response(str(e), httplib.CONFLICT)

        if balance:
            # make initial deposit
            raiden_service_result = self.raiden_api.deposit(
                token_address,
                partner_address,
                balance
            )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return jsonify_with_response(data=result.data, status_code=httplib.CREATED)
Example #25
0
    def _deposit(self, channel, balance):
        if channel.state != CHANNEL_STATE_OPENED:
            return api_error(
                errors="Can't deposit on a closed channel",
                status_code=HTTPStatus.CONFLICT,
            )

        try:
            raiden_service_result = self.raiden_api.deposit(
                channel.token_address,
                channel.partner_address,
                balance
            )
        except InsufficientFunds as e:
            return api_error(
                errors=str(e),
                status_code=HTTPStatus.PAYMENT_REQUIRED
            )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #26
0
    def _settle(self, channel):
        if channel.state != CHANNEL_STATE_CLOSED:
            return api_error(
                errors='Attempted to settle a channel at its {} state'.format(
                    channel.state,
                ),
                status_code=HTTPStatus.CONFLICT,
            )

        try:
            raiden_service_result = self.raiden_api.settle(
                channel.token_address,
                channel.partner_address
            )
        except InvalidState:
            return api_error(
                errors='Settlement period is not yet over',
                status_code=HTTPStatus.CONFLICT,
            )

        result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
        return api_response(result=result.data)
Example #27
0
    def patch_channel(self, channel_address, balance=None, state=None):
        if balance is not None and state is not None:
            return api_error(
                errors='Can not update balance and change channel state at the same time',
                status_code=httplib.CONFLICT,
            )
        elif balance is None and state is None:
            return api_error(
                errors="Nothing to do. Should either provide 'balance' or 'state' argument",
                status_code=httplib.BAD_REQUEST,
            )

        # find the channel
        try:
            channel = self.raiden_api.get_channel(channel_address)
        except ChannelNotFound:
            return api_error(
                errors="Requested channel {} not found".format(
                    address_encoder(channel_address)
                ),
                status_code=httplib.CONFLICT
            )

        current_state = channel.state

        # if we patch with `balance` it's a deposit
        if balance is not None:
            if current_state != CHANNEL_STATE_OPENED:
                return api_error(
                    errors="Can't deposit on a closed channel",
                    status_code=httplib.CONFLICT,
                )
            try:
                raiden_service_result = self.raiden_api.deposit(
                    channel.token_address,
                    channel.partner_address,
                    balance
                )
            except InsufficientFunds as e:
                return api_error(
                    errors=str(e),
                    status_code=httplib.PAYMENT_REQUIRED
                )
            result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
            return api_response(result=result.data)

        if state == CHANNEL_STATE_CLOSED:
            if current_state != CHANNEL_STATE_OPENED:
                return api_error(
                    errors='Attempted to close an already closed channel',
                    status_code=httplib.CONFLICT,
                )
            raiden_service_result = self.raiden_api.close(
                channel.token_address,
                channel.partner_address
            )
            result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
            return api_response(result=result.data)

        if state == CHANNEL_STATE_SETTLED:
            if current_state != CHANNEL_STATE_CLOSED:
                return api_error(
                    errors='Attempted to settle a channel at its '
                    '{} state'.format(current_state),
                    status_code=httplib.CONFLICT,
                )
            try:
                raiden_service_result = self.raiden_api.settle(
                    channel.token_address,
                    channel.partner_address
                )
            except InvalidState:
                return api_error(
                    errors='Settlement period is not yet over',
                    status_code=httplib.CONFLICT,
                )
            else:
                result = self.channel_schema.dump(channel_to_api_dict(raiden_service_result))
                return api_response(result=result.data)

        # should never happen, channel_state is validated in the schema
        return api_error(
            errors='Provided invalid channel state {}'.format(state),
            status_code=httplib.BAD_REQUEST,
        )
Example #28
0
 def get_channel(self, channel_address):
     channel = self.raiden_api.get_channel(channel_address)
     result = self.channel_schema.dump(channel_to_api_dict(channel))
     return api_response(result=result.data)
Example #29
0
 def get_channel(self, channel_address):
     channel = self.raiden_api.get_channel(channel_address)
     result = self.channel_schema.dump(channel_to_api_dict(channel))
     return jsonify(result.data)
Example #30
0
 def get_channel(self, channel_address):
     channel = self.raiden_api.get_channel(channel_address)
     return self.channel_schema.dumps(channel_to_api_dict(channel))