예제 #1
0
    def validate_negotiated_nonce(self):
        """

        :return:
        """
        # to validate the negotiated nonce
        valid_trade, valid_nonce = Channel.latest_valid_trade(
            self.channel_name)

        nonce = self.nego_nonce or self.nonce
        if valid_nonce and valid_nonce + 1 == nonce:
            return valid_trade
        else:
            raise GoTo(
                EnumResponseStatus.RESPONSE_TRADE_COULD_NOT_BE_OVERWRITTEN,
                'Could not use negotiated nonce <{}>, current valid nonce<{}>'.
                format(self.nego_nonce, valid_nonce))
예제 #2
0
    def create_resign_message_body(cls,
                                   wallet_url,
                                   channel_name,
                                   nonce,
                                   is_resign_response=False):
        """

        :param wallet_url: current opened wallet url
        :param channel_name:
        :param nonce:
        :param is_resign_response: if True, it means has received the peer resign request
        :return:
        """
        if not (channel_name and isinstance(nonce, int)):
            raise GoTo(
                EnumResponseStatus.RESPONSE_ILLEGAL_INPUT_PARAMETER,
                'Illegal parameters: channel_name<{}> or nonce<{}, type:{}>'.
                format(channel_name, nonce, type(nonce)))

        # record the nonce negotiated by partner of the transaction with nonce
        # required is True
        if is_resign_response:
            nego_nonce = nonce
            pre_nonce = nonce
            pre_trade = Channel.query_trade(channel_name, nego_nonce)
        else:
            pre_trade, pre_nonce = Channel.latest_valid_trade(channel_name)
            nego_nonce = pre_nonce + 1 if isinstance(pre_nonce, int) else None

        # does founder practise fraud ???
        if not (pre_trade and nego_nonce) or cls._FOUNDER_NONCE >= nego_nonce:
            raise GoTo(EnumResponseStatus.RESPONSE_TRADE_WITH_INCORRECT_NONCE,
                       'Could not finish this transaction because ')

        # initialize some local variables
        trade_role = pre_trade.role
        trade_type = pre_trade.type
        trade_state = pre_trade.state

        # local variables
        resign_body = {'Nonce': str(pre_nonce)}
        need_update_balance = False

        # is partner role of this transaction
        if EnumTradeRole.TRADE_ROLE_PARTNER.name == trade_role and EnumTradeState.confirming.name == trade_state:
            # update the resign_body by the different trade type
            if EnumTradeType.TRADE_TYPE_RSMC.name == trade_type:
                if pre_trade.peer_commitment:
                    # update the trade to confirmed state directly
                    Channel.update_trade(channel_name,
                                         pre_nonce,
                                         state=EnumTradeState.confirmed.name)

                    # need update channel balance
                    # need_update_balance = True
                else:
                    # need resign this RSMC transaction by peer
                    resign_body.update({'Commitment': pre_trade.commitment})
            elif EnumTradeType.TRADE_TYPE_HTLC.name == trade_type:
                if pre_trade.peer_commitment and pre_trade.peer_delay_commitment:
                    # update the trade to confirmed state directly
                    Channel.update_trade(channel_name,
                                         pre_nonce,
                                         state=EnumTradeState.confirming.name)
                    # need update channel balance
                    # need_update_balance = True
                else:
                    # need resign this HTLC transaction by peer
                    resign_body.update({'Commitment': pre_trade.commitment})
                    resign_body.update(
                        {'DelayCommitment': pre_trade.delay_commitment})
            else:
                LOG.error(
                    'Unsupported trade type<{}> to resign in partner<{}> side'.
                    format(trade_type, wallet_url))
                return None, pre_trade

            # need update the channel balance or not???
            # if need_update_balance:
            #     channel = Channel(channel_name)
            #     self_address, _, _ = uri_parser(wallet_url)
            #     peer_address, _, _ = uri_parser(channel.peer_uri(wallet_url))
            #
            #     # ToDo: if need, here need add asset type check in future
            #     Channel.update_channel(channel_name, balance={
            #         self_address: {pre_trade.asset_type: pre_trade.balance},
            #         peer_address: {pre_trade.asset_type: pre_trade.peer_balance}
            #     })
        elif is_resign_response is True and EnumTradeRole.TRADE_ROLE_FOUNDER.name == trade_role and \
                (EnumTradeState.confirmed.name == trade_state or (EnumTradeState.confirming.name == trade_state and
                                                                  EnumTradeType.TRADE_TYPE_HTLC.name == trade_type)):

            if EnumTradeType.TRADE_TYPE_RSMC.name == trade_type:
                if pre_trade.peer_commitment:
                    resign_body.update({'Commitment': pre_trade.commitment})
                else:
                    # stop transaction ????
                    pass
            elif EnumTradeType.TRADE_TYPE_HTLC.name == trade_type:
                if pre_trade.peer_commitment and pre_trade.peer_delay_commitment:
                    resign_body.update({'Commitment': pre_trade.commitment})
                    resign_body.update(
                        {'DelayCommitment': pre_trade.delay_commitment})
            else:
                LOG.error(
                    'Unsupported trade type<{}> to resign in founder<{}> side'.
                    format(trade_type, wallet_url))
                return None, pre_trade
        else:
            return None, pre_trade

        # Previous transaction need to be resigned by peer
        if 'Commitment' in resign_body:
            return resign_body, pre_trade

        return None, pre_trade