Пример #1
0
    def settle(self):
        if log.isEnabledFor(logging.INFO):
            log.info(
                'settle called',
                node=pex(self.node_address),
            )

        transaction_hash = estimate_and_transact(
            self.proxy,
            'settle',
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            log.info(
                'settle failed',
                node=pex(self.node_address),
                contract=pex(self.address),
            )
            self._check_exists()
            raise TransactionThrew('Settle', receipt_or_none)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'settle sucessfull',
                node=pex(self.node_address),
                contract=pex(self.address),
            )
Пример #2
0
    def add_token(self, token_address):
        if not isaddress(token_address):
            raise ValueError('token_address must be a valid address')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'addToken',
            self.startgas,
            self.gasprice,
            token_address,
        )

        self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('AddToken', receipt_or_none)

        manager_address = self.manager_address_by_token(token_address)

        if manager_address is None:
            log.error('Transaction failed and check_transaction_threw didnt detect it')
            raise RuntimeError('channelManagerByToken failed')

        if log.isEnabledFor(logging.INFO):
            log.info(
                'add_token called',
                token_address=pex(token_address),
                registry_address=pex(self.address),
                manager_address=pex(manager_address),
            )

        return manager_address
Пример #3
0
    def add_token(self, token_address):
        if not isaddress(token_address):
            raise ValueError('token_address must be a valid address')

        transaction_hash = estimate_and_transact(
            self.proxy.addToken,
            self.startgas,
            self.gasprice,
            token_address,
        )

        self.client.poll(transaction_hash.decode('hex'),
                         timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('AddToken', receipt_or_none)

        manager_address = self.manager_address_by_token(token_address)

        if manager_address is None:
            log.error(
                'Transaction failed and check_transaction_threw didnt detect it'
            )
            raise RuntimeError('channelManagerByToken failed')

        if log.isEnabledFor(logging.INFO):
            log.info(
                'add_token called',
                token_address=pex(token_address),
                registry_address=pex(self.address),
                manager_address=pex(manager_address),
            )

        return manager_address
Пример #4
0
    def new_netting_channel(self, other_peer, settle_timeout):
        if not isaddress(other_peer):
            raise ValueError('The other_peer must be a valid address')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        local_address = privatekey_to_address(self.client.privkey)
        if local_address == other_peer:
            raise SamePeerAddress(
                'The other peer must not have the same address as the client.')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'newChannel',
            self.startgas,
            self.gasprice,
            other_peer,
            settle_timeout,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.call(
            'getChannelWith',
            other_peer,
            startgas=self.startgas,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(local_address),
                      peer2=pex(other_peer))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'new_netting_channel called',
                peer1=pex(local_address),
                peer2=pex(other_peer),
                netting_channel=pex(netting_channel_address_bin),
            )

        return netting_channel_address_bin
Пример #5
0
    def close(self, nonce, transferred_amount, locksroot, extra_hash,
              signature):
        """ Close the channel using the provided balance proof.

        Raises:
            AddressWithoutCode: If the channel was settled prior to the call.
        """
        if log.isEnabledFor(logging.INFO):
            log.info(
                'close called',
                node=pex(self.node_address),
                contract=pex(self.address),
                nonce=nonce,
                transferred_amount=transferred_amount,
                locksroot=encode_hex(locksroot),
                extra_hash=encode_hex(extra_hash),
                signature=encode_hex(signature),
            )

        transaction_hash = estimate_and_transact(
            self.proxy,
            'close',
            nonce,
            transferred_amount,
            locksroot,
            extra_hash,
            signature,
        )
        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            log.critical(
                'close failed',
                node=pex(self.node_address),
                contract=pex(self.address),
                nonce=nonce,
                transferred_amount=transferred_amount,
                locksroot=encode_hex(locksroot),
                extra_hash=encode_hex(extra_hash),
                signature=encode_hex(signature),
            )
            self._check_exists()
            raise TransactionThrew('Close', receipt_or_none)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'close sucessfull',
                node=pex(self.node_address),
                contract=pex(self.address),
                nonce=nonce,
                transferred_amount=transferred_amount,
                locksroot=encode_hex(locksroot),
                extra_hash=encode_hex(extra_hash),
                signature=encode_hex(signature),
            )
Пример #6
0
    def deposit(self, amount):
        """ Deposit amount token in the channel.

        Raises:
            AddressWithoutCode: If the channel was settled prior to the call.
            RuntimeError: If the netting channel token address is empty.
        """
        if not isinstance(amount, (int, long)):
            raise ValueError('amount needs to be an integral number.')

        token_address = self.token_address()

        token = Token(
            self.client,
            token_address,
            self.startgas,
            self.gasprice,
            self.poll_timeout,
        )
        current_balance = token.balance_of(self.node_address)

        if current_balance < amount:
            raise ValueError(
                'deposit [{}] cant be larger than the available balance [{}].'.
                format(
                    amount,
                    current_balance,
                ))

        if log.isEnabledFor(logging.INFO):
            log.info('deposit called',
                     contract=pex(self.address),
                     amount=amount)

        transaction_hash = estimate_and_transact(
            self.proxy,
            'deposit',
            self.startgas,
            self.gasprice,
            amount,
        )

        self.client.poll(
            unhexlify(transaction_hash),
            timeout=self.poll_timeout,
        )

        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            log.critical('deposit failed', contract=pex(self.address))
            self._check_exists()
            raise TransactionThrew('Deposit', receipt_or_none)

        if log.isEnabledFor(logging.INFO):
            log.info('deposit sucessfull',
                     contract=pex(self.address),
                     amount=amount)
Пример #7
0
    def update_transfer(self, nonce, transferred_amount, locksroot, extra_hash,
                        signature):
        if signature:
            if log.isEnabledFor(logging.INFO):
                log.info(
                    'updateTransfer called',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    nonce=nonce,
                    transferred_amount=transferred_amount,
                    locksroot=encode_hex(locksroot),
                    extra_hash=encode_hex(extra_hash),
                    signature=encode_hex(signature),
                )

            transaction_hash = estimate_and_transact(
                self.proxy,
                'updateTransfer',
                nonce,
                transferred_amount,
                locksroot,
                extra_hash,
                signature,
            )

            self.client.poll(
                unhexlify(transaction_hash),
                timeout=self.poll_timeout,
            )

            receipt_or_none = check_transaction_threw(self.client,
                                                      transaction_hash)
            if receipt_or_none:
                log.critical(
                    'updateTransfer failed',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    nonce=nonce,
                    transferred_amount=transferred_amount,
                    locksroot=encode_hex(locksroot),
                    extra_hash=encode_hex(extra_hash),
                    signature=encode_hex(signature),
                )
                self._check_exists()
                raise TransactionThrew('Update Transfer', receipt_or_none)

            if log.isEnabledFor(logging.INFO):
                log.info(
                    'updateTransfer sucessfull',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    nonce=nonce,
                    transferred_amount=transferred_amount,
                    locksroot=encode_hex(locksroot),
                    extra_hash=encode_hex(extra_hash),
                    signature=encode_hex(signature),
                )
Пример #8
0
    def approve(self, contract_address, allowance):
        """ Aprove `contract_address` to transfer up to `deposit` amount of token. """
        # TODO: check that `contract_address` is a netting channel and that
        # `self.address` is one of the participants (maybe add this logic into
        # `NettingChannel` and keep this straight forward)

        transaction_hash = estimate_and_transact(
            self.proxy,
            'approve',
            self.startgas,
            self.gasprice,
            contract_address,
            allowance,
        )

        self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)

        if receipt_or_none:
            user_balance = self.balance_of(self.client.sender)

            # If the balance is zero, either the smart contract doesnt have a
            # balanceOf function or the actual balance is zero
            if user_balance == 0:
                msg = (
                    "Approve failed. \n"
                    "Your account balance is 0 (zero), either the smart "
                    "contract is not a valid ERC20 token or you don't have funds "
                    "to use for openning a channel. "
                )
                raise TransactionThrew(msg, receipt_or_none)

            # The approve call failed, check the user has enough balance
            # (assuming the token smart contract may check for the maximum
            # allowance, which is not necessarily the case)
            elif user_balance < allowance:
                msg = (
                    'Approve failed. \n'
                    'Your account balance is {}, nevertheless the call to '
                    'approve failed. Please make sure the corresponding smart '
                    'contract is a valid ERC20 token.'
                ).format(user_balance)
                raise TransactionThrew(msg, receipt_or_none)

            # If the user has enough balance, warn the user the smart contract
            # may not have the approve function.
            else:
                msg = (
                    'Approve failed. \n'
                    'Your account balance is {}, the request allowance is {}. '
                    'The smart contract may be rejecting your request for the '
                    'lack of balance.'
                ).format(user_balance, allowance)
                raise TransactionThrew(msg, receipt_or_none)
Пример #9
0
    def approve(self, contract_address, allowance):
        """ Aprove `contract_address` to transfer up to `deposit` amount of token. """
        # TODO: check that `contract_address` is a netting channel and that
        # `self.address` is one of the participants (maybe add this logic into
        # `NettingChannel` and keep this straight forward)

        transaction_hash = estimate_and_transact(
            self.proxy,
            'approve',
            self.startgas,
            self.gasprice,
            contract_address,
            allowance,
        )

        self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)

        if receipt_or_none:
            user_balance = self.balance_of(self.client.sender)

            # If the balance is zero, either the smart contract doesnt have a
            # balanceOf function or the actual balance is zero
            if user_balance == 0:
                msg = (
                    "Approve failed. \n"
                    "Your account balance is 0 (zero), either the smart "
                    "contract is not a valid ERC20 token or you don't have funds "
                    "to use for openning a channel. "
                )
                raise TransactionThrew(msg, receipt_or_none)

            # The approve call failed, check the user has enough balance
            # (assuming the token smart contract may check for the maximum
            # allowance, which is not necessarily the case)
            elif user_balance < allowance:
                msg = (
                    'Approve failed. \n'
                    'Your account balance is {}, nevertheless the call to '
                    'approve failed. Please make sure the corresponding smart '
                    'contract is a valid ERC20 token.'
                ).format(user_balance)
                raise TransactionThrew(msg, receipt_or_none)

            # If the user has enough balance, warn the user the smart contract
            # may not have the approve function.
            else:
                msg = (
                    'Approve failed. \n'
                    'Your account balance is {}, the request allowance is {}. '
                    'The smart contract may be rejecting your request for the '
                    'lack of balance.'
                ).format(user_balance, allowance)
                raise TransactionThrew(msg, receipt_or_none)
Пример #10
0
    def add_token(self, token_address):
        if not isaddress(token_address):
            raise ValueError('token_address must be a valid address')

        log.info(
            'add_token called',
            node=pex(self.node_address),
            token_address=pex(token_address),
            registry_address=pex(self.address),
        )

        transaction_hash = estimate_and_transact(
            self.proxy,
            'addToken',
            self.address,
            token_address,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            log.info(
                'add_token failed',
                node=pex(self.node_address),
                token_address=pex(token_address),
                registry_address=pex(self.address),
            )
            raise TransactionThrew('AddToken', receipt_or_none)

        manager_address = self.manager_address_by_token(token_address)

        if manager_address is None:
            log.info(
                'add_token failed and check_transaction_threw didnt detect it',
                node=pex(self.node_address),
                token_address=pex(token_address),
                registry_address=pex(self.address),
            )

            raise RuntimeError('channelManagerByToken failed')

        log.info(
            'add_token sucessful',
            node=pex(self.node_address),
            token_address=pex(token_address),
            registry_address=pex(self.address),
            manager_address=pex(manager_address),
        )

        return manager_address
Пример #11
0
    def transfer(self, to_address, amount):
        transaction_hash = estimate_and_transact(
            self.proxy.transfer,  # pylint: disable=no-member
            self.startgas,
            self.gasprice,
            to_address,
            amount,
        )

        self.client.poll(unhexlify(transaction_hash))
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('Transfer', receipt_or_none)
Пример #12
0
    def transfer(self, to_address, amount):
        transaction_hash = estimate_and_transact(
            self.proxy,
            'transfer',
            to_address,
            amount,
        )

        self.client.poll(unhexlify(transaction_hash))
        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('Transfer', receipt_or_none)
Пример #13
0
    def transfer(self, to_address, amount):
        transaction_hash = estimate_and_transact(
            self.proxy,
            'transfer',
            self.startgas,
            self.gasprice,
            to_address,
            amount,
        )

        self.client.poll(unhexlify(transaction_hash))
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('Transfer', receipt_or_none)
Пример #14
0
    def withdraw(self, unlock_proofs):
        # force a list to get the length (could be a generator)
        unlock_proofs = list(unlock_proofs)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'withdraw called',
                node=pex(self.node_address),
                contract=pex(self.address),
            )

        failed = False
        for merkle_proof, locked_encoded, secret in unlock_proofs:
            if isinstance(locked_encoded, messages.Lock):
                raise ValueError('unlock must be called with a lock encoded `.as_bytes`')

            merkleproof_encoded = ''.join(merkle_proof)

            transaction_hash = estimate_and_transact(
                self.proxy,
                'withdraw',
                locked_encoded,
                merkleproof_encoded,
                secret,
            )

            self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)
            receipt_or_none = check_transaction_threw(self.client, transaction_hash)
            lock = messages.Lock.from_bytes(locked_encoded)
            if receipt_or_none:
                lock = messages.Lock.from_bytes(locked_encoded)
                log.critical(
                    'withdraw failed',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    lock=lock,
                )
                self._check_exists()
                failed = True

            elif log.isEnabledFor(logging.INFO):
                log.info(
                    'withdraw sucessfull',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    lock=lock,
                )

        if failed:
            raise TransactionThrew('Withdraw', receipt_or_none)
Пример #15
0
    def approve(self, contract_address, allowance):
        """ Aprove `contract_address` to transfer up to `deposit` amount of token. """
        # TODO: check that `contract_address` is a netting channel and that
        # `self.address` is one of the participants (maybe add this logic into
        # `NettingChannel` and keep this straight forward)

        transaction_hash = estimate_and_transact(
            self.proxy.approve,
            self.startgas,
            self.gasprice,
            contract_address,
            allowance,
        )

        self.client.poll(transaction_hash.decode('hex'), timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)
        if receipt_or_none:
            raise TransactionThrew('Approve', receipt_or_none)
Пример #16
0
    def withdraw(self, unlock_proof):
        if log.isEnabledFor(logging.INFO):
            log.info(
                'withdraw called',
                node=pex(self.node_address),
                contract=pex(self.address),
            )

        if isinstance(unlock_proof.lock_encoded, messages.Lock):
            raise ValueError(
                'unlock must be called with a lock encoded `.as_bytes`')

        merkleproof_encoded = ''.join(unlock_proof.merkle_proof)

        transaction_hash = estimate_and_transact(
            self.proxy,
            'withdraw',
            unlock_proof.lock_encoded,
            merkleproof_encoded,
            unlock_proof.secret,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)

        if receipt_or_none:
            log.critical(
                'withdraw failed',
                node=pex(self.node_address),
                contract=pex(self.address),
                lock=unlock_proof,
            )
            self._check_exists()
            raise TransactionThrew('Withdraw', receipt_or_none)

        elif log.isEnabledFor(logging.INFO):
            log.info(
                'withdraw sucessfull',
                node=pex(self.node_address),
                contract=pex(self.address),
                lock=unlock_proof,
            )
Пример #17
0
    def settle(self):
        """ Settle the channel.

        Raises:
            ChannelBusyError: If the channel is busy with another operation
        """
        if log.isEnabledFor(logging.INFO):
            log.info(
                'settle called',
                node=pex(self.node_address),
            )

        if not self.channel_operations_lock.acquire(0):
            raise ChannelBusyError(
                f'Channel with address {self.address} is '
                f'busy with another ongoing operation'
            )

        self.channel_operations_lock.release()

        with self.channel_operations_lock:
            transaction_hash = estimate_and_transact(
                self.proxy,
                'settle',
            )

            self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)
            receipt_or_none = check_transaction_threw(self.client, transaction_hash)
            if receipt_or_none:
                log.info(
                    'settle failed',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                )
                self._check_exists()
                raise TransactionThrew('Settle', receipt_or_none)

            if log.isEnabledFor(logging.INFO):
                log.info(
                    'settle successful',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                )
Пример #18
0
    def settle(self):
        if log.isEnabledFor(logging.INFO):
            log.info('settle called')

        transaction_hash = estimate_and_transact(
            self.proxy.settle,
            self.startgas,
            self.gasprice,
        )

        self.client.poll(transaction_hash.decode('hex'), timeout=self.poll_timeout)
        receipt_or_none = check_transaction_threw(self.client, transaction_hash)
        if receipt_or_none:
            log.info('settle failed', contract=pex(self.address))
            self._check_exists()
            raise TransactionThrew('Settle', receipt_or_none)

        if log.isEnabledFor(logging.INFO):
            log.info('settle sucessfull', contract=pex(self.address))
Пример #19
0
    def _new_netting_channel(self, other_peer, settle_timeout):
        if self.channel_exists(other_peer):
            raise DuplicatedChannelError('Channel with given partner address already exists')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'newChannel',
            other_peer,
            settle_timeout,
        )

        if not transaction_hash:
            raise RuntimeError('open channel transaction failed')

        self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        return transaction_hash
Пример #20
0
    def new_netting_channel(self, other_peer: Address,
                            settle_timeout: int) -> Address:
        """ Creates and deploys a new netting channel contract.

        Args:
            other_peer: The peer to open the channel with.
            settle_timeout: The settle timout to use for this channel.

        Returns:
            The address of the new netting channel.
        """
        if not isaddress(other_peer):
            raise ValueError('The other_peer must be a valid address')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise InvalidSettleTimeout(
                'settle_timeout must be in range [{}, {}]'.format(
                    NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                    NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        local_address = privatekey_to_address(self.client.privkey)
        if local_address == other_peer:
            raise SamePeerAddress(
                'The other peer must not have the same address as the client.')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'newChannel',
            other_peer,
            settle_timeout,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.call(
            'getChannelWith',
            other_peer,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(local_address),
                      peer2=pex(other_peer))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'new_netting_channel called',
                peer1=pex(local_address),
                peer2=pex(other_peer),
                netting_channel=pex(netting_channel_address_bin),
            )

        return netting_channel_address_bin
Пример #21
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        if not isaddress(peer1):
            raise ValueError('The peer1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        if peer1 == peer2:
            raise SamePeerAddress('Peer1 and peer2 must not be equal')

        if privatekey_to_address(self.client.privkey) == peer1:
            other = peer2
        else:
            other = peer1

        transaction_hash = estimate_and_transact(
            self.proxy.newChannel,
            self.startgas,
            self.gasprice,
            other,
            settle_timeout,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.getChannelWith.call(
            other,
            startgas=self.startgas,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(peer1),
                      peer2=pex(peer2))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'new_netting_channel called',
                peer1=pex(peer1),
                peer2=pex(peer2),
                netting_channel=pex(netting_channel_address_bin),
            )

        return netting_channel_address_bin
Пример #22
0
    def close(self, nonce, transferred_amount, locksroot, extra_hash, signature):
        """ Close the channel using the provided balance proof.

        Raises:
            AddressWithoutCode: If the channel was settled prior to the call.
            ChannelBusyError: If the channel is busy with another operation.
        """

        log.info(
            'close called',
            node=pex(self.node_address),
            contract=pex(self.address),
            nonce=nonce,
            transferred_amount=transferred_amount,
            locksroot=encode_hex(locksroot),
            extra_hash=encode_hex(extra_hash),
            signature=encode_hex(signature),
        )

        if not self.channel_operations_lock.acquire(blocking=False):
            raise ChannelBusyError(
                f'Channel with address {self.address} is '
                f'busy with another ongoing operation.'
            )

        with releasing(self.channel_operations_lock):
            transaction_hash = estimate_and_transact(
                self.proxy,
                'close',
                nonce,
                transferred_amount,
                locksroot,
                extra_hash,
                signature,
            )
            self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout)

            receipt_or_none = check_transaction_threw(self.client, transaction_hash)
            if receipt_or_none:
                log.critical(
                    'close failed',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                    nonce=nonce,
                    transferred_amount=transferred_amount,
                    locksroot=encode_hex(locksroot),
                    extra_hash=encode_hex(extra_hash),
                    signature=encode_hex(signature),
                )
                self._check_exists()
                raise TransactionThrew('Close', receipt_or_none)

            log.info(
                'close successful',
                node=pex(self.node_address),
                contract=pex(self.address),
                nonce=nonce,
                transferred_amount=transferred_amount,
                locksroot=encode_hex(locksroot),
                extra_hash=encode_hex(extra_hash),
                signature=encode_hex(signature),
            )
Пример #23
0
    def deposit(self, amount):
        """ Deposit amount token in the channel.

        Raises:
            AddressWithoutCode: If the channel was settled prior to the call.
            ChannelBusyError: If the channel is busy with another operation
            RuntimeError: If the netting channel token address is empty.
        """
        if not isinstance(amount, int):
            raise ValueError('amount needs to be an integral number.')

        token_address = self.token_address()

        token = Token(
            self.client,
            token_address,
            self.poll_timeout,
        )
        current_balance = token.balance_of(self.node_address)

        if current_balance < amount:
            raise ValueError('deposit [{}] cant be larger than the available balance [{}].'.format(
                amount,
                current_balance,
            ))

        log.info(
            'deposit called',
            node=pex(self.node_address),
            contract=pex(self.address),
            amount=amount,
        )

        if not self.channel_operations_lock.acquire(blocking=False):
            raise ChannelBusyError(
                f'Channel with address {self.address} is '
                f'busy with another ongoing operation.'
            )

        with releasing(self.channel_operations_lock):
            transaction_hash = estimate_and_transact(
                self.proxy,
                'deposit',
                amount,
            )

            self.client.poll(
                unhexlify(transaction_hash),
                timeout=self.poll_timeout,
            )

            receipt_or_none = check_transaction_threw(self.client, transaction_hash)
            if receipt_or_none:
                log.critical(
                    'deposit failed',
                    node=pex(self.node_address),
                    contract=pex(self.address),
                )

                self._check_exists()
                raise TransactionThrew('Deposit', receipt_or_none)

            log.info(
                'deposit successful',
                node=pex(self.node_address),
                contract=pex(self.address),
                amount=amount,
            )