예제 #1
0
    def connect(
        self,
        funds: typing.TokenAmount,
        initial_channel_target: int = 3,
        joinable_funds_target: float = 0.4,
    ) -> None:
        """Connect to the network.

        Subsequent calls to `connect` are allowed, but will only affect the spendable
        funds and the connection strategy parameters for the future. `connect` will not
        close any channels.

        Note: the ConnectionManager does not discriminate manually opened channels from
        automatically opened ones. If the user manually opened channels, those deposit
        amounts will affect the funding per channel and the number of new channels opened.

        Args:
            funds: Target amount of tokens spendable to join the network.
            initial_channel_target: Target number of channels to open.
            joinable_funds_target: Amount of funds not initially assigned.
        """
        token = self.raiden.proxy_manager.token(self.token_address)
        token_balance = token.balance_of(self.raiden.address)

        if token_balance < funds:
            raise InvalidAmount(
                f"Insufficient balance for token {to_checksum_address(self.token_address)}"
            )

        if funds <= 0:
            raise InvalidAmount("The funds to use in the connection need to be a positive integer")

        if joinable_funds_target < 0 or joinable_funds_target > 1:
            raise InvalidAmount(
                f"joinable_funds_target should be between 0 and 1. Given: {joinable_funds_target}"
            )

        with self.lock:
            self.funds = funds
            self.initial_channel_target = initial_channel_target
            self.joinable_funds_target = joinable_funds_target

            log_open_channels(self.raiden, self.registry_address, self.token_address, funds)

            qty_network_channels = views.count_token_network_channels(
                views.state_from_raiden(self.raiden), self.registry_address, self.token_address
            )

            if not qty_network_channels:
                log.info(
                    "Bootstrapping token network.",
                    node=to_checksum_address(self.raiden.address),
                    network_id=to_checksum_address(self.registry_address),
                    token_id=to_checksum_address(self.token_address),
                )
                self.api.channel_open(
                    self.registry_address, self.token_address, self.BOOTSTRAP_ADDR
                )
            else:
                self._open_channels()
예제 #2
0
파일: python.py 프로젝트: zheewang/raiden
    def transfer_async(self, token_address, amount, target, identifier=None):
        # pylint: disable=too-many-arguments

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

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

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

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

        graph = self.raiden.token_to_channelgraph[token_address]
        if not graph.has_path(self.raiden.address, target):
            raise NoPathError('No path to address found')

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

        async_result = self.raiden.mediated_transfer_async(
            token_address,
            amount,
            target,
            identifier,
        )
        return async_result
예제 #3
0
    def transfer_async(self, token_address, amount, target, identifier=None):

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

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

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

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

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            self.raiden.default_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)

        async_result = self.raiden.mediated_transfer_async(
            token_address,
            amount,
            target,
            identifier,
        )
        return async_result
예제 #4
0
    def transfer_async(self, token_address, amount, target, identifier=None):
        # pylint: disable=too-many-arguments

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

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

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

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

        graph = self.raiden.channelgraphs[token_address]
        if not graph.has_path(self.raiden.address, target):
            raise NoPathError('No path to address found')

        async_result = self.raiden.transfer_async(
            token_address,
            amount,
            target,
            identifier=identifier,
        )
        return async_result
예제 #5
0
    def connect(
            self,
            funds: typing.TokenAmount,
            initial_channel_target: int = 3,
            joinable_funds_target: float = 0.4,
    ):
        """Connect to the network.

        Subsequent calls to `connect` are allowed, but will only affect the spendable
        funds and the connection strategy parameters for the future. `connect` will not
        close any channels.

        Note: the ConnectionManager does not discriminate manually opened channels from
        automatically opened ones. If the user manually opened channels, those deposit
        amounts will affect the funding per channel and the number of new channels opened.

        Args:
            funds: Target amount of tokens spendable to join the network.
            initial_channel_target: Target number of channels to open.
            joinable_funds_target: Amount of funds not initially assigned.
        """
        token = self.raiden.chain.token(self.token_address)
        token_balance = token.balance_of(self.raiden.address)

        if token_balance < funds:
            raise InvalidAmount(
                f'Insufficient balance for token {pex(self.token_address)}',
            )

        if funds <= 0:
            raise InvalidAmount(
                'The funds to use in the connection need to be a positive integer',
            )

        with self.lock:
            self.funds = funds
            self.initial_channel_target = initial_channel_target
            self.joinable_funds_target = joinable_funds_target

            log_open_channels(self.raiden, self.registry_address, self.token_address, funds)

            qty_network_channels = views.count_token_network_channels(
                views.state_from_raiden(self.raiden),
                self.registry_address,
                self.token_address,
            )

            if not qty_network_channels:
                log.debug('bootstrapping token network.')
                # make ourselves visible
                self.api.channel_open(
                    self.registry_address,
                    self.token_address,
                    self.BOOTSTRAP_ADDR,
                )
            else:
                self._open_channels()
예제 #6
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
예제 #7
0
    def connect(
        self,
        funds: typing.TokenAmount,
        initial_channel_target: int = 3,
        joinable_funds_target: float = 0.4,
    ) -> None:
        """Connect to the network.

        Subsequent calls to `connect` are allowed, but will only affect the spendable
        funds and the connection strategy parameters for the future. `connect` will not
        close any channels.

        Note: the ConnectionManager does not discriminate manually opened channels from
        automatically opened ones. If the user manually opened channels, those deposit
        amounts will affect the funding per channel and the number of new channels opened.

        Args:
            funds: Target amount of tokens spendable to join the network.
            initial_channel_target: Target number of channels to open.
            joinable_funds_target: Amount of funds not initially assigned.
        """
        confirmed_block_identifier = views.get_confirmed_blockhash(self.raiden)
        token = self.raiden.proxy_manager.token(self.token_address,
                                                confirmed_block_identifier)
        token_balance = token.balance_of(self.raiden.address)

        if token_balance < funds:
            raise InvalidAmount(
                f"Insufficient balance for token {to_checksum_address(self.token_address)}"
            )

        if funds <= 0:
            raise InvalidAmount(
                "The funds to use in the connection need to be a positive integer"
            )

        if joinable_funds_target < 0 or joinable_funds_target > 1:
            raise InvalidAmount(
                f"joinable_funds_target should be between 0 and 1. Given: {joinable_funds_target}"
            )

        with self.lock:
            self.funds = funds
            self.initial_channel_target = initial_channel_target
            self.joinable_funds_target = joinable_funds_target

            log_open_channels(self.raiden, self.registry_address,
                              self.token_address, funds)
            have_online_partners, potential_partners = self._have_online_channels_to_connect_to(
            )
            if not have_online_partners:
                bootstrap_address = (self.BOOTSTRAP_ADDR
                                     if len(potential_partners) == 0 else
                                     random.choice(potential_partners))
                log.info(
                    "Bootstrapping token network.",
                    node=to_checksum_address(self.raiden.address),
                    network_id=to_checksum_address(self.registry_address),
                    token_id=to_checksum_address(self.token_address),
                    bootstrap_address=to_checksum_address(bootstrap_address),
                )
                try:
                    self.api.channel_open(
                        registry_address=self.registry_address,
                        token_address=self.token_address,
                        partner_address=bootstrap_address,
                    )
                except DuplicatedChannelError:
                    # If we have none else to connect to and connect got called twice
                    # then it's possible to already have channel with the bootstrap node.
                    # In that case do nothing
                    pass
            else:
                self._open_channels()
예제 #8
0
    def transfer_async(
        self,
        registry_address: typing.PaymentNetworkID,
        token_address: typing.TokenAddress,
        amount: typing.TokenAmount,
        target: typing.Address,
        identifier: typing.PaymentID = None,
        secret: typing.Secret = None,
        secret_hash: typing.SecretHash = 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.')

        if secret is not None:
            if len(secret) != SECRET_HEXSTRING_LENGTH:
                raise InvalidSecretOrSecretHash(
                    'secret length should be ' + str(SECRET_HEXSTRING_LENGTH) +
                    '.', )
            if not is_hex(secret):
                raise InvalidSecretOrSecretHash(
                    'provided secret is not an hexadecimal string.')
            secret = to_bytes(hexstr=secret)

        if secret_hash is not None:
            if len(secret_hash) != SECRET_HASH_HEXSTRING_LENGTH:
                raise InvalidSecretOrSecretHash(
                    'secret_hash length should be ' +
                    str(SECRET_HASH_HEXSTRING_LENGTH) + '.', )
            if not is_hex(secret_hash):
                raise InvalidSecretOrSecretHash(
                    'secret_hash is not an hexadecimal string.')
            secret_hash = to_bytes(hexstr=secret_hash)

        if secret is None and secret_hash is not None:
            raise InvalidSecretOrSecretHash(
                'secret_hash without a secret is not supported yet.')

        if secret is not None and secret_hash is not None and secret_hash != sha3(
                secret):
            raise InvalidSecretOrSecretHash(
                'provided secret and secret_hash do not match.')

        valid_tokens = views.get_token_identifiers(
            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,
        )
        payment_status = self.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=target,
            identifier=identifier,
            secret=secret,
            secret_hash=secret_hash,
        )
        return payment_status
예제 #9
0
    def transfer_async(
        self,
        registry_address: PaymentNetworkID,
        token_address: TokenAddress,
        amount: TokenAmount,
        target: Address,
        identifier: PaymentID = None,
        secret: Secret = None,
        secrethash: SecretHash = None,
    ):
        current_state = views.state_from_raiden(self.raiden)
        payment_network_identifier = self.raiden.default_registry.address

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

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

        if amount > UINT256_MAX:
            raise InvalidAmount("Amount too large")

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

        if token_address not in views.get_token_identifiers(current_state, registry_address):
            raise UnknownTokenAddress("Token address is not known.")

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

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

        if secret is not None and not isinstance(secret, typing.T_Secret):
            raise InvalidSecret("secret is not valid.")

        if secrethash is not None and not isinstance(secrethash, typing.T_SecretHash):
            raise InvalidSecretHash("secrethash is not valid.")

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

        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=current_state,
            payment_network_id=payment_network_identifier,
            token_address=token_address,
        )
        payment_status = self.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=target,
            identifier=identifier,
            secret=secret,
            secrethash=secrethash,
        )
        return payment_status
예제 #10
0
    def transfer_async(
        self,
        registry_address: TokenNetworkRegistryAddress,
        token_address: TokenAddress,
        amount: PaymentAmount,
        target: TargetAddress,
        identifier: PaymentID = None,
        secret: Secret = None,
        secrethash: SecretHash = None,
        lock_timeout: BlockTimeout = None,
    ) -> "PaymentStatus":
        current_state = views.state_from_raiden(self.raiden)
        token_network_registry_address = self.raiden.default_registry.address

        if not isinstance(amount, int):  # pragma: no unittest
            raise InvalidAmount("Amount not a number")

        if Address(target) == self.address:
            raise SamePeerAddress("Address must be different than ours")

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

        if amount > UINT256_MAX:
            raise InvalidAmount("Amount too large")

        if not is_binary_address(token_address):
            raise InvalidBinaryAddress("token address is not valid.")

        if token_address not in views.get_token_identifiers(
                current_state, registry_address):
            raise UnknownTokenAddress("Token address is not known.")

        if not is_binary_address(target):
            raise InvalidBinaryAddress("target address is not valid.")

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

        if secret is not None and not isinstance(secret, T_Secret):
            raise InvalidSecret("secret is not valid.")

        if secrethash is not None and not isinstance(secrethash, T_SecretHash):
            raise InvalidSecretHash("secrethash is not valid.")

        if identifier is None:
            identifier = create_default_identifier()

        if identifier <= 0:
            raise InvalidPaymentIdentifier(
                "Payment identifier cannot be 0 or negative")

        if identifier > UINT64_MAX:
            raise InvalidPaymentIdentifier("Payment identifier is too large")

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

        token_network_address = views.get_token_network_address_by_token_address(
            chain_state=current_state,
            token_network_registry_address=token_network_registry_address,
            token_address=token_address,
        )

        if token_network_address is None:
            raise UnknownTokenAddress(
                f"Token {to_checksum_address(token_address)} is not registered "
                f"with the network {to_checksum_address(registry_address)}.")

        payment_status = self.raiden.mediated_transfer_async(
            token_network_address=token_network_address,
            amount=amount,
            target=target,
            identifier=identifier,
            secret=secret,
            secrethash=secrethash,
            lock_timeout=lock_timeout,
        )
        return payment_status
예제 #11
0
    def transfer_async(
        self,
        registry_address: PaymentNetworkID,
        token_address: TokenAddress,
        amount: TokenAmount,
        target: Address,
        identifier: PaymentID = None,
        secret: Secret = None,
        secrethash: SecretHash = 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.")

        if secret is not None:
            if len(secret) != SECRET_HEXSTRING_LENGTH:
                raise InvalidSecretOrSecretHash(
                    "secret length should be " + str(SECRET_HEXSTRING_LENGTH) + "."
                )
            if not is_hex(secret):
                raise InvalidSecretOrSecretHash("provided secret is not an hexadecimal string.")
            secret = to_bytes(hexstr=secret)

        if secrethash is not None:
            if len(secrethash) != SECRETHASH_HEXSTRING_LENGTH:
                raise InvalidSecretOrSecretHash(
                    "secret_hash length should be " + str(SECRETHASH_HEXSTRING_LENGTH) + "."
                )
            if not is_hex(secrethash):
                raise InvalidSecretOrSecretHash("secret_hash is not an hexadecimal string.")
            secrethash = to_bytes(hexstr=secrethash)

        # if both secret and secrethash were provided we check that sha3(secret)
        # matches the secerthash. Note that it is valid to provide a secert_hash
        # without providing a secret
        if secret is not None and secrethash is not None and secrethash != sha3(secret):
            raise InvalidSecretOrSecretHash("provided secret and secret_hash do not match.")

        valid_tokens = views.get_token_identifiers(
            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,
        )
        payment_status = self.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=target,
            identifier=identifier,
            secret=secret,
            secrethash=secrethash,
        )
        return payment_status