예제 #1
0
파일: channel.py 프로젝트: wjlu/trinity-eth
    def quick_close(cls, channel_name, wallet=None, cli=False, trigger=None):
        """

        :param channel_name:
        :param wallet:
        :param cli:
        :param trigger:
        :return:
        """
        try:
            channel = cls.query_channel(channel_name)[0]

            # get peer address
            peer = channel.src_addr
            if wallet.url == peer:
                peer = channel.dest_addr

            # start trigger to close channel quickly
            trigger(wallet, peer, channel_name, 'TNC')
        except Exception as error:
            if cli:
                console_log.error(
                    'Failed to close channel: {}'.format(channel_name))
            LOG.error('Failed to close channel<{}>, Exception: {}'.format(
                channel_name, error))
예제 #2
0
 def _wapper(self, arguments):
     ar_len = length if isinstance(length, list) else [length]
     if len(arguments) in ar_len:
         return func(self, arguments)
     else:
         console_log.error(
             "Arguments length should be {}".format(ar_len))
         self.help()
         return
예제 #3
0
 def wrapper(*args, **kwargs):
     try:
         callback(*args, **kwargs)
     except Exception as error:
         console_log.error(
             'Error occurred to run command: {}. Please check logs for details.'
             .format(command))
         LOG.error(
             'Error occurred to run command: {}. Exception: {}'.format(
                 command, error))
예제 #4
0
    def channel_qrcode(self, arguments):
        """

        :param arguments:
        :return:
        """
        enable = get_arg(arguments, 1)
        if enable.upper() not in ["ON", "OFF"]:
            console_log.error("should be on or off")
        self.qrcode = True if enable.upper() == "ON" else False
        console_log.console(
            "Qrcode opened") if self.qrcode else console_log.info(
                "Qrcode closed")
        return None
예제 #5
0
    def do_channel(self, arguments):
        """

        :param arguments:
        :return:
        """
        command = get_arg(arguments)
        channel_command = [i.split()[1] for i in self.user_commands]
        if command not in channel_command:
            console_log.error("no support command, please check the help")
            self.help()
            return

        if command == 'create':
            self.do_channel_create(arguments)

        elif command == "enable":
            if not self.enable_channel():
                self._channel_noopen()

        elif command == "tx":
            self.channel_trans(arguments)

        elif command == "qrcode":
            self.channel_qrcode(arguments)

        elif command == "close":
            self.channel_close(arguments)

        elif command == "force-close":
            self.channel_force_close(arguments)

        elif command == "htlc-unlock":
            self.channel_htlc_unlock(arguments)

        elif command == "peer":
            self.channel_peer(arguments)

        elif command == "payment":
            self.channel_payment(arguments)

        elif command == "show":
            self.channel_show(arguments)

        elif command == "deposit_limit":
            self.channel_deposit_limit(arguments)
        else:
            return None
예제 #6
0
    def do_send(self, arguments):
        """

        :param arguments:
        :return:
        """

        if not self.Wallet:
            print("please open a wallet")
            return False
        if len(arguments) < 3:
            print("Not enough arguments")
            return False

        assetId = get_arg(arguments).upper()
        address_to = get_arg(arguments, 1)
        amount = float(get_arg(arguments, 2))
        if amount <= 0:
            console_log.error("value can not less then 0")
            return None

        if not assetId in self.Wallet.SupportAssert:
            console_log.error("No support assert")
            return None

        gaslimit = int(get_arg(arguments, 3)) if get_arg(arguments,
                                                         3) else None
        gasprice = int(get_arg(arguments, 4)) if get_arg(arguments,
                                                         4) else None

        if assetId == "ETH":
            if amount >= self.Wallet.eth_balance:
                console_log.error("No balance")
                return None

            try:
                res = self.Wallet.send_eth(address_to, amount, gaslimit)
                print("txid: 0x" + res)
            except Exception as e:
                print("send failed %s" % e)
        elif assetId == "TNC":
            if amount > self.Wallet.tnc_balance or self.Wallet.eth_balance < 0:
                console_log.error("No balance")
                return None
            try:
                res = self.Wallet.send_erc20(assetId, address_to, amount,
                                             gaslimit, gasprice)
                print("txid: 0x" + res)
            except Exception as e:
                print("send failed %s" % e)

        else:
            pass
        return
예제 #7
0
    def generate_payment_code(cls,
                              receiver,
                              asset_type,
                              value,
                              hashcode,
                              comments='',
                              cli=False):
        """"""
        if 0 >= int(value):
            console_log.error('Not support negative number.')
            return

        if not IS_SUPPORTED_ASSET_TYPE(asset_type):
            text = 'AssetType: {} is not supported'.format(asset_type)
            LOG.error(text)
            if cli:
                console_log.error(text)

            return None

        asset_type = asset_type.replace('0x', '')
        if asset_type.upper() in SUPPORTED_ASSET_TYPE.keys():
            asset_type = asset_type.upper()

        hashcode = hashcode.strip()

        code = "{uri}&{net_magic}&{hashcode}&{asset_type}&{payment}&{comments}".format(
            uri=receiver,
            net_magic=get_magic(),
            hashcode=hashcode,
            asset_type=asset_type,
            payment=value,
            comments=comments)
        base58_code = base58.b58encode(code.encode())
        try:
            return "TN{}".format(base58_code.decode())
        except Exception as error:
            LOG.debug('generate_payment_code error: {}'.format(error))
            return "TN{}".format(base58_code)
예제 #8
0
    def channel_show(self, arguments):
        """

        :param arguments:
        :return:
        """
        subcommand = get_arg(arguments, 1)
        if not subcommand:
            self.help()
            return None
        if subcommand.upper() == "URI":
            console_log.console(self.Wallet.url)
        elif subcommand.upper() == "TRANS_HISTORY":
            channel_name = get_arg(arguments, 2)
            if channel_name is None:
                console_log.error("No provide channel")
                return None
            tx_his = Channel.batch_query_trade(channel_name)
            for tx in tx_his:
                console_log.console(tx)
            return None
        else:
            self.help()
        return None
예제 #9
0
    def channel_payment(self, arguments):
        """

        :param arguments:
        :return:
        """
        asset_type = get_arg(arguments, 1)
        if not check_support_asset_type(asset_type):
            console_log.error(
                "No support asset, current just support {}".format(
                    SupportAssetType.SupportAssetType))
            return None
        value = TrinityNumber(get_arg(arguments, 2).strip()).number
        if not value:
            console_log.error("command not give the count")
            return None
        try:
            if 0 >= value or not check_float_decimals(value, asset_type):
                console_log.error("value should not be less than 0")
                return None
        except ValueError:
            console_log.error("value format error")
            return None
        comments = " ".join(arguments[3:])
        comments = comments if comments else "None"
        if len(comments) > 128:
            console_log.error("comments length should be less than 128")
            return None
        try:
            hash_r, rcode = Payment.create_hr()
            Channel.add_payment(None, hash_r, rcode, value)
            paycode = Payment.generate_payment_code(self.Wallet.url,
                                                    asset_type, value, hash_r,
                                                    comments, True)
        except Exception as e:
            LOG.error(e)
            console_log.error("Get payment link error, please check the log")
            return None
        if self.qrcode:
            qrcode_terminal.draw(paycode, version=4)
        console_log.console(paycode)
        return None
예제 #10
0
 def wapper(self, *args, **kwargs):
     if not self.Wallet:
         console_log.error("No opened wallet, please open wallet first")
         return None
     else:
         return func(self, *args, **kwargs)
예제 #11
0
    def channel_trans(self, arguments):
        """

        :param arguments:
        :return:
        """

        if len(arguments) == 2:
            # payment code
            pay_code = get_arg(arguments, 1)
            result, info = Payment.decode_payment_code(pay_code)
            if result:
                receiver = info.get("uri")
                net_magic = info.get('net_magic')
                if not net_magic or net_magic != str(get_magic()):
                    console_log.error("No correct net magic")
                    return None
                hashcode = info.get("hashcode")
                asset_type = info.get("asset_type")
                # asset_type = get_asset_type_name(asset_type)
                count = info.get("payment")
                comments = info.get("comments")
                console_log.info("will pay {} {} to {} comments {}".format(
                    TrinityNumber.convert_to_number(count), asset_type,
                    receiver, comments))
            else:
                console_log.error("The payment code is not correct")
                return
        else:
            receiver = get_arg(arguments, 1)
            asset_type = get_arg(arguments, 2)
            count = TrinityNumber(get_arg(arguments, 3).strip()).number
            hashcode = get_arg(arguments, 4)
            if not receiver or not asset_type or not count:
                self.help()
                return None

            asset_type = asset_type.upper() if check_support_asset_type(
                asset_type) else None
            if not asset_type:
                console_log.error(
                    "No support asset, current just support {}".format(
                        str(SupportAssetType.SupportAssetType)))
                return None

            if 0 >= count:
                console_log.warn('Not support negative number or zero.')
                return None

        # query channels by address
        channel_set = Channel.get_channel(self.Wallet.url, receiver,
                                          EnumChannelState.OPENED)
        if channel_set and channel_set[0]:
            Channel.transfer(channel_set[0].channel,
                             self.Wallet,
                             receiver,
                             asset_type,
                             count,
                             cli=True,
                             comments=hashcode,
                             trigger=RsmcMessage.create)
        else:
            if not hashcode:
                console_log.error("No hashcode")
                return None
            try:
                message = {
                    "MessageType": "GetRouterInfo",
                    "Sender": self.Wallet.url,
                    "Receiver": receiver,
                    "AssetType": asset_type,
                    "NetMagic": get_magic(),
                    "MessageBody": {
                        "AssetType": asset_type,
                        "Value": count
                    }
                }
                result = gate_way.get_router_info(message)
                routerinfo = json.loads(result.get("result"))
            except Exception as error:
                LOG.error(
                    'Exception occurred during get route info. Exception: {}'.
                    format(error))
                console_log.warning('No router was found.')
                return
            else:
                router = routerinfo.get("RouterInfo")
                if not router:
                    LOG.error('Router between {} and {} was not found.'.format(
                        self.Wallet.url, receiver))
                    console_log.error('Router not found for HTLC transfer.')
                    return

            full_path = router.get("FullPath")
            LOG.info("Get Router {}".format(str(full_path)))

            next_jump = router.get("Next")
            LOG.info("Get Next {}".format(str(next_jump)))
            fee_router = [
                i for i in full_path if i[0] not in (self.Wallet.url, receiver)
            ]
            if fee_router:
                # fee = reduce(lambda x, y:x+y,[TrinityNumber(str(i[1]).strip()).number for i in fee_router])
                fee = reduce(lambda x, y: x + y,
                             [float(i[1]) for i in fee_router])
            else:
                fee = 0

            fee = TrinityNumber(str(fee)).number
            count = int(count) + fee
            fee = fee / pow(10, 8)
            receiver = full_path[1][0]
            channel_set = Channel.get_channel(self.Wallet.url, receiver,
                                              EnumChannelState.OPENED)
            if not (channel_set and channel_set[0]):
                print('No OPENED channel was found for HTLC trade.')
                return
            LOG.info("Get Fee {}".format(fee))
            answer = prompt(
                "You will pay extra fee {}. Do you wish continue this transaction? [Yes/No]>"
                .format(fee))
            if answer.upper() in ["YES", "Y"]:
                channel_name = channel_set[0].channel
                Channel.transfer(channel_name,
                                 self.Wallet,
                                 receiver,
                                 asset_type,
                                 count,
                                 hashcode,
                                 router=full_path,
                                 next_jump=full_path[2][0],
                                 cli=True,
                                 trigger=HtlcMessage.create)

            else:
                return
예제 #12
0
    def do_channel_create(self, arguments):
        """

        :return:
        """

        partner = get_arg(arguments, 1)
        if not is_correct_uri(partner):
            console_log.error("No correct uri format")
            return None

        asset_type = get_arg(arguments, 2)
        asset_type = asset_type.upper() if check_support_asset_type(
            asset_type) else None
        if not asset_type:
            console_log.error(
                "No support asset, current just support {}".format(
                    str(SupportAssetType.SupportAssetType)))
            return None

        try:
            deposit_limit = DepositAuth.deposit_limit()
            deposit_cmp = TrinityNumber(str(deposit_limit)).number
            deposit = TrinityNumber(get_arg(arguments, 3).strip()).number
            #when partner_deposit not given ,partner_deposit is equal to deposit
            if get_arg(arguments, 4) == None:
                partner_deposit = deposit
            elif TrinityNumber(get_arg(arguments, 4)).number == None:
                console_log.error("partner_deposit is not valid")
                return
            else:
                partner_deposit = TrinityNumber(get_arg(arguments, 4)).number

            if deposit_cmp > deposit:
                console_log.error(
                    "Founder's Deposit MUST be larger than {}".format(
                        deposit_limit))
                return None
            elif deposit_cmp > partner_deposit:
                console_log.error(
                    "Partner's Deposit should be larger than {}".format(
                        deposit_limit))
                return None
            elif partner_deposit > deposit:
                console_log.error(
                    "Founder's Deposit should not be less than Partner's")
                return None
        except ValueError:
            console_log.error(
                "Founder's Deposit should not be less than Partner'")
            return None

        if not check_partner(self.Wallet, partner):
            console_log.error(
                "Partner URI is not correct, Please check the partner uri")
            return None

        if not check_onchain_balance(self.Wallet.address, asset_type, deposit):
            console_log.error(
                "Now the balance on-chain is less than the deposit.")
            return None

        if not check_onchain_balance(partner.strip().split("@")[0], asset_type,
                                     partner_deposit):
            console_log.error(
                "Partner balance on chain is less than the deposit")
            return None

        Channel.create(self.Wallet,
                       self.Wallet.url,
                       partner,
                       asset_type,
                       deposit,
                       partner_deposit,
                       trigger=FounderMessage.create)
예제 #13
0
파일: channel.py 프로젝트: wjlu/trinity-eth
    def create(cls,
               wallet,
               founder,
               partner,
               asset_type,
               deposit,
               partner_deposit=None,
               comments=None,
               trigger=None,
               cli=True):
        """
            Provide one method to be called by the wallet prompt console.
        :param wallet:
        :param partner:
        :param asset_type:
        :param deposit:
        :param partner_deposit:
        :param comments:
        :param cli:
        :return:
        """
        if not (wallet and partner and asset_type and deposit):
            LOG.error('Invalid parameters:wallet<{}>, founder<{}>, partner<{}>, asset_type<{}>, deposit<{}>' \
                      .format(wallet, founder, partner, asset_type, deposit))
            # here we could use some hooks to register event to handle output console ????
            console_log.error(
                'Illegal mandatory parameters. Please check in your command.')
            return False

        # use deposit as default value for both partners if partner's deposit is not set:
        if not partner_deposit:
            partner_deposit = deposit

        # judge whether the channel exist or not
        if Channel.get_channel(founder, partner, EnumChannelState.OPENED):
            console_log.warning('OPENED channel already exists.')
            return False
        else:
            # creating channel is ongoing
            # channel = Channel.get_channel(founder, partner, EnumChannelState.OPENING)
            # if :
            #     console.warning('Channel {} is on the way. Please try later if failed')
            #     return
            pass

        channel_name = cls.new_channel_name(founder, partner)
        if cli:
            deposit = int(deposit)
            partner_deposit = int(partner_deposit)
            if 0 >= deposit or 0 >= partner_deposit:
                LOG.error('Could not register channel because of illegal deposit<{}:{}>.'\
                          .format(deposit, partner_deposit))
                return False

            try:
                trigger(wallet, channel_name, asset_type, founder, deposit,
                        partner, partner_deposit, comments)
            except Exception as error:
                LOG.info('Create channel<{}> failed. Exception: {}'.format(
                    channel_name, error))
                return False

        return True