コード例 #1
0
ファイル: token_network.py プロジェクト: azhang2013/raiden
    def _check_channel_state_for_withdraw(
        self,
        participant1,
        participant2,
        channel_identifier,
        withdraw_amount,
    ):
        participant_details = self.detail_participants(
            participant1,
            participant2,
            channel_identifier,
        )

        if participant_details.our_details.withdrawn > withdraw_amount:
            raise WithdrawMismatch('Withdraw amount decreased')

        channel_state = self._get_channel_state(
            participant1=participant1,
            participant2=participant2,
            channel_identifier=channel_identifier,
        )

        if channel_state in (ChannelState.NONEXISTENT, ChannelState.REMOVED):
            raise RaidenUnrecoverableError(
                f'Channel between participant {participant1} '
                f'and {participant2} does not exist', )
        elif channel_state == ChannelState.SETTLED:
            raise RaidenUnrecoverableError(
                'A settled channel cannot be closed', )
        elif channel_state == ChannelState.CLOSED:
            raise RaidenRecoverableError('Channel is already closed', )
コード例 #2
0
ファイル: token_network.py プロジェクト: azhang2013/raiden
    def withdraw(
        self,
        channel_identifier: typing.ChannelID,
        partner: typing.Address,
        total_withdraw: int,
        partner_signature: typing.Address,
        signature: typing.Signature,
    ):
        log_details = {
            'token_network': pex(self.address),
            'node': pex(self.node_address),
            'partner': pex(partner),
            'total_withdraw': total_withdraw,
            'partner_signature': encode_hex(partner_signature),
            'signature': encode_hex(signature),
        }
        log.debug('setTotalWithdraw called', **log_details)

        self._check_for_outdated_channel(
            self.node_address,
            partner,
            channel_identifier,
        )

        current_withdraw = self.detail_participant(
            channel_identifier,
            self.node_address,
            partner,
        ).withdrawn
        amount_to_withdraw = total_withdraw - current_withdraw

        if total_withdraw < current_withdraw:
            msg = (
                f'Current withdraw ({current_withdraw}) is already larger '
                f'than the requested total withdraw amount ({total_withdraw})',
            )
            log.critical(f'setTotalWithdraw failed, {msg}', **log_details)
            raise WithdrawMismatch(msg)

        if amount_to_withdraw <= 0:
            msg = f'withdraw {amount_to_withdraw} must be greater than 0.'
            log.critical(f'setTotalWithdraw failed, {msg}', **log_details)
            raise ValueError(msg)

        with self.channel_operations_lock[partner]:
            transaction_hash = self.proxy.transact(
                'setTotalWithdraw',
                channel_identifier,
                self.node_address,
                total_withdraw,
                partner_signature,
                signature,
            )
            self.client.poll(transaction_hash)

            receipt_or_none = check_transaction_threw(self.client,
                                                      transaction_hash)
            if receipt_or_none:
                log.critical('setTotalWithdraw failed', **log_details)

                self._check_channel_state_for_withdraw(
                    self.node_address,
                    partner,
                    channel_identifier,
                    total_withdraw,
                )

                raise TransactionThrew('Withdraw', receipt_or_none)

            log.info('setTotalWithdraw successful', **log_details)
コード例 #3
0
    def set_total_channel_withdraw(
        self,
        registry_address: TokenNetworkRegistryAddress,
        token_address: TokenAddress,
        partner_address: Address,
        total_withdraw: WithdrawAmount,
        retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ) -> None:
        """ Set the `total_withdraw` in the channel with the peer at `partner_address` and the
        given `token_address`.

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

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

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

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

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

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

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

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

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

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