Beispiel #1
0
    def create(cls,
               wallet,
               channel_name,
               asset_type,
               tx_nonce,
               sender,
               receiver,
               payment,
               sender_balance,
               receiver_balance,
               hashcode,
               delay_block,
               peer_commitment,
               peer_hlock_commitment,
               router,
               next_router,
               comments=None):
        """

        :param wallet:
        :param channel_name:
        :param asset_type:
        :param tx_nonce:
        :param sender:
        :param receiver:
        :param payment:
        :param sender_balance:
        :param receiver_balance:
        :param hashcode:
        :param delay_block:
        :param peer_commitment:
        :param peer_hlock_commitment:
        :param router:
        :param next_router:
        :param comments:
        :return:
        """
        # get nonce from latest trade
        _, nonce = HtlcResponsesMessage.check_nonce(tx_nonce, channel_name)

        # start to verify balance
        payer_address, _, _ = uri_parser(sender)
        payee_address, _, _ = uri_parser(receiver)
        asset_type = asset_type.upper()

        # check balance
        _, payer_balance, payee_balance = HtlcResponsesMessage.check_balance(
            channel_name,
            asset_type,
            payer_address,
            sender_balance,
            payee_address,
            receiver_balance,
            is_htcl_type=True,
            payment=payment)

        # 2 parts in htlc message: conclusive and inconclusive part
        sign_hashcode, sign_rcode = cls.get_default_rcode()
        rsmc_commitment = HtlcResponsesMessage.sign_content(
            typeList=RsmcMessage._sign_type_list,
            valueList=[
                channel_name, nonce, payer_address, payer_balance,
                payee_address, payee_balance, sign_hashcode, sign_rcode
            ],
            privtKey=wallet._key.private_key_string)

        hlock_commitment = HtlcResponsesMessage.sign_content(
            start=5,
            typeList=HtlcResponsesMessage._sign_type_list,
            valueList=[
                channel_name, payer_address, payee_address, delay_block,
                int(payment), hashcode
            ],
            privtKey=wallet._key.private_key_string)

        # # ToDo: need re-sign all unconfirmed htlc message later
        htlc_trade = Channel.htlc_trade(
            type=EnumTradeType.TRADE_TYPE_HTLC,
            role=EnumTradeRole.TRADE_ROLE_PARTNER,
            asset_type=asset_type,
            balance=payee_balance,
            peer_balance=payer_balance,
            payment=payment,
            hashcode=hashcode,
            delay_block=delay_block,
            commitment=rsmc_commitment,
            peer_commitment=peer_commitment,
            delay_commitment=hlock_commitment,
            peer_delay_commitment=peer_hlock_commitment,
            channel=channel_name)
        Channel.add_trade(channel_name, nonce=nonce, **htlc_trade)

        # create message
        message = HtlcResponsesMessage.create_message_header(
            receiver, sender, HtlcResponsesMessage._message_name, channel_name,
            asset_type, tx_nonce)
        message = message.message_header
        message.update({
            'Router': router,
            'Next': next_router,
        })
        message_body = {
            'SenderBalance': payer_balance,
            'ReceiverBalance': payee_balance,
            'Commitment': rsmc_commitment,
            'Payment': payment,
            'DelayBlock': delay_block,
            'DelayCommitment': hlock_commitment,
            'HashR': hashcode
        }

        # orgnize the message
        message.update({'MessageBody': message_body})
        message.update({'Status': EnumResponseStatus.RESPONSE_OK.name})
        if comments:
            message.update({'Comments': comments})

        # Before the response ok, we could update the channel balance
        HtlcResponsesMessage.update_balance_for_channel(channel_name,
                                                        asset_type,
                                                        payer_address,
                                                        payee_address,
                                                        payment,
                                                        is_htlc_type=True)

        # send response ok message to peer
        HtlcResponsesMessage.send(message)

        return
Beispiel #2
0
    def create(cls,
               wallet,
               channel_name,
               asset_type,
               sender,
               receiver,
               payment,
               hashcode,
               router,
               next_router,
               current_channel=None,
               comments=None):
        """

        :param channel_name:
        :param wallet:
        :param sender:
        :param receiver:
        :param asset_type:
        :param payment:
        :param nonce:
        :param hashcode:
        :param router:
        :param next_router:
        :param comments:
        :return:
        """
        cls.check_channel_state(channel_name)
        cls.check_router(router, hashcode)
        cls.check_asset_type(asset_type)
        cls.check_both_urls(sender, receiver)
        cls.check_router(router, hashcode)

        # get nonce
        nonce = Channel.new_nonce(channel_name)
        if HtlcMessage._FOUNDER_NONCE > nonce:
            raise GoTo(
                EnumResponseStatus.RESPONSE_TRADE_WITH_INCORRECT_NONCE,
                'HtlcMessage::create: Incorrect nonce<{}> for channel<{}>'.
                format(nonce, channel_name))

        # get sender & receiver address from sender or receiver
        payer_address, _, _ = uri_parser(sender)
        payee_address, _, _ = uri_parser(receiver)
        asset_type = asset_type.upper()

        # check whether the balance is enough or not
        channel = Channel(channel_name)
        balance = channel.balance
        _, payer_balance, payee_balance = HtlcMessage.calculate_balance_after_payment(
            balance.get(payer_address, {}).get(asset_type),
            balance.get(payee_address, {}).get(asset_type),
            payment,
            is_htlc_type=True)

        # calculate the end block height
        jumps_index = HtlcMessage.this_jump(sender, router)
        end_block_height = cls.get_locked_block_height(len(router),
                                                       jumps_index)

        # Htlc is made up of 2 parts: rsmc and hlock part
        sign_hashcode, sign_rcode = cls.get_default_rcode()
        rsmc_commitment = HtlcMessage.sign_content(
            typeList=RsmcMessage._sign_type_list,
            valueList=[
                channel_name, nonce, payer_address, payer_balance,
                payee_address, payee_balance, sign_hashcode, sign_rcode
            ],
            privtKey=wallet._key.private_key_string)

        # hlock parts
        hlock_commitment = HtlcMessage.sign_content(
            start=5,
            typeList=HtlcMessage._sign_type_list,
            valueList=[
                channel_name, payer_address, payee_address, end_block_height,
                int(payment), hashcode
            ],
            privtKey=wallet._key.private_key_string)

        # # add trade to database
        htlc_trade = Channel.htlc_trade(type=EnumTradeType.TRADE_TYPE_HTLC,
                                        role=EnumTradeRole.TRADE_ROLE_FOUNDER,
                                        asset_type=asset_type,
                                        balance=payer_balance,
                                        peer_balance=payee_balance,
                                        payment=payment,
                                        hashcode=hashcode,
                                        delay_block=end_block_height,
                                        commitment=rsmc_commitment,
                                        delay_commitment=hlock_commitment)
        if current_channel:
            htlc_trade.update({'channel': current_channel})
        Channel.add_trade(channel_name, nonce=nonce, **htlc_trade)

        # generate the messages
        message_body = {
            'SenderBalance': payer_balance,
            'ReceiverBalance': payee_balance,
            'Commitment': rsmc_commitment,
            'Payment': payment,
            'DelayBlock': end_block_height,
            'DelayCommitment': hlock_commitment,
            'HashR': hashcode
        }

        message = HtlcMessage.create_message_header(sender, receiver,
                                                    HtlcMessage._message_name,
                                                    channel_name, asset_type,
                                                    nonce)
        message = message.message_header
        message.update({
            'Router': router,
            'Next': next_router,
        })
        message.update({'MessageBody': message_body})

        if comments:
            message.update({'Comments': comments})

        HtlcMessage.send(message)

        return None