Esempio n. 1
0
    def notify_peer_payment_finished(self,):
        try:
            payment_record = Channel.query_payment(self.channel_name, self.comments)[0]
            receiver = payment_record.receiver
        except:
            LOG.warning('No payment record with code<{}> is found'.format(self.comments))
            pass
        else:
            PaymentAck.create(self.wallet.url, receiver, self.channel_name, self.asset_type, self.nonce,
                              self.comments)

        return
Esempio n. 2
0
    def trigger_htlc_to_next_jump(self):
        """"""
        self.router, _ = self.exclude_wallet_from_router(
            self.wallet.url, self.router)
        if not self.check_if_the_last_router():
            next_router = self.next_jump
            LOG.debug('Get Next Router {} from {}'.format(
                str(next_router), self.router))

            if not next_router:
                raise GoTo(
                    EnumResponseStatus.RESPONSE_ROUTER_WITH_ILLEGAL_NEXT_JUMP,
                    'Illegal next jump<{}> in router<{}>'.format(
                        next_router, self.router))

            # to get channel between current wallet and next jump
            channel_set = Channel.get_channel(self.wallet.url,
                                              next_router,
                                              state=EnumChannelState.OPENED)
            if not (channel_set and channel_set[0]):
                raise GoTo(
                    EnumResponseStatus.RESPONSE_CHANNEL_NOT_FOUND,
                    'No OPENED channel is found between {} and {}.'.format(
                        self.wallet.url, next_router))
            channel_set = channel_set[0]

            if channel_set.channel == self.channel_name:
                LOG.warn('Has reached receiver of HTLC transaction.')
                return

            # calculate fee and transfer to next jump
            fee = TrinityNumber(str(self.get_fee(self.wallet.url))).number
            payment = self.big_number_calculate(self.payment, fee, False)
            receiver = next_router
            HtlcMessage.create(channel_set.channel,
                               self.asset_type,
                               self.wallet.url,
                               receiver,
                               payment,
                               self.hashcode,
                               self.router,
                               current_channel=self.channel_name,
                               comments=self.comments)

            # record channel of next jump in current htlc trade
            Channel.update_trade(self.channel_name,
                                 self.nonce,
                                 channel=channel_set.channel)

            APIStatistics.update_statistics(self.wallet.address, htlc_free=fee)
        else:
            # trigger RResponse
            Channel.update_payment(self.channel_name, self.hashcode)
            payment_trade = Channel.query_payment(self.channel_name,
                                                  self.hashcode)
            if not (payment_trade and payment_trade[0]):
                raise GoTo(
                    EnumResponseStatus.RESPONSE_TRADE_HASHR_NOT_FOUND,
                    'Rcode not found for hashcode<{}>'.format(self.hashcode))

            payment_trade = payment_trade[0]

            try:
                RResponse.create(self.channel_name, self.asset_type,
                                 self.nonce, self.wallet.url, self.sender,
                                 self.hashcode, payment_trade.rcode,
                                 self.comments)

                # update the htlc trade history
                Channel.update_trade(self.channel_name,
                                     self.nonce,
                                     rcode=payment_trade.rcode)
            except Exception as error:
                LOG.exception(
                    'Failed triggerring to send RResponse for HashR<{}>. Exception: {}'
                    .format(self.hashcode, error))
Esempio n. 3
0
    def handle(self):
        super(HtlcMessage, self).handle()

        trigger_rresponse = False
        status = EnumResponseStatus.RESPONSE_OK
        try:
            self.check_hashcode_used(self.channel_name, self.hashcode)
            self.check_channel_state(self.channel_name)
            self.check_router(self.router, self.hashcode)
            self.verify()
            _, nonce = self.check_nonce(self.nonce, self.channel_name)
            _, payer_balance, payee_balance = self.check_balance(
                self.channel_name,
                self.asset_type,
                self.sender_address,
                self.sender_balance,
                self.receiver_address,
                self.receiver_balance,
                is_htcl_type=True,
                payment=self.payment)

            sign_hashcode, sign_rcode = self.get_default_rcode()
            self.check_signature(self.wallet,
                                 type_list=RsmcMessage._sign_type_list,
                                 value_list=[
                                     self.channel_name, self.nonce,
                                     self.sender_address,
                                     int(self.sender_balance),
                                     self.receiver_address,
                                     int(self.receiver_balance), sign_hashcode,
                                     sign_rcode
                                 ],
                                 signature=self.commitment)

            self.check_signature(self.wallet,
                                 type_list=self._sign_type_list,
                                 value_list=[
                                     self.channel_name, self.sender_address,
                                     self.receiver_address,
                                     int(self.delay_block),
                                     int(self.payment), self.hashcode
                                 ],
                                 signature=self.delay_commitment)

            # transform the message to the next router if not last router node
            next_router = self.next_router
            if not self.check_if_the_last_router():
                next_router = self.get_next_router()
                LOG.debug('Get Next Router {}'.format(str(next_router)))

                # to get channel
                channel_set = Channel.get_channel(
                    self.wallet.url,
                    next_router,
                    state=EnumChannelState.OPENED)
                if not (channel_set and channel_set[0]):
                    status = EnumResponseStatus.RESPONSE_CHANNEL_NOT_FOUND
                    raise GoTo(
                        EnumResponseStatus.RESPONSE_CHANNEL_NOT_FOUND,
                        'No OPENED channel is found between {} and {}.'.format(
                            self.wallet.url, next_router))
                channel_set = channel_set[0]

                # calculate fee and transfer to next jump
                fee = TrinityNumber(str(self.get_fee(self.wallet.url))).number
                payment = self.big_number_calculate(self.payment, fee, False)
                receiver = next_router
                self.create(self.wallet,
                            channel_set.channel,
                            self.asset_type,
                            self.wallet.url,
                            receiver,
                            payment,
                            self.hashcode,
                            self.router,
                            next_router,
                            current_channel=self.channel_name,
                            comments=self.comments)
            else:
                Channel.update_payment(self.channel_name, self.hashcode)
                payment_trade = Channel.query_payment(self.channel_name,
                                                      self.hashcode)
                if not (payment_trade and payment_trade[0]):
                    raise GoTo(
                        EnumResponseStatus.RESPONSE_TRADE_HASHR_NOT_FOUND,
                        'Rcode not found for hashcode<{}>'.format(
                            self.hashcode))

                payment_trade = payment_trade[0]
                # trigger RResponse
                trigger_rresponse = True

            # send response to receiver
            HtlcResponsesMessage.create(
                self.wallet, self.channel_name, self.asset_type, self.nonce,
                self.sender, self.receiver, self.payment, self.sender_balance,
                self.receiver_balance, self.hashcode, self.delay_block,
                self.commitment, self.delay_commitment, self.router,
                next_router, self.comments)

            # means last receiver has received this htlc message, then update this trade record.
            if trigger_rresponse:
                try:
                    RResponse.create(self.channel_name, self.asset_type,
                                     self.nonce, self.wallet.url, self.sender,
                                     self.hashcode, payment_trade.rcode,
                                     self.comments)

                    # update the htlc trade history
                    Channel.update_trade(self.channel_name,
                                         self.nonce,
                                         rcode=payment_trade.rcode)
                except Exception as error:
                    LOG.error('Failed triggerring to send RResponse for HashR<{}>. Exception: {}'\
                              .format(self.hashcode, error))
        except TrinityException as error:
            LOG.error(error)
            status = error.reason
        except Exception as error:
            LOG.error(
                'Failed to handle Htlc message for channel<{}>, HashR<{}>. Exception:{}'
                .format(self.channel_name, self.hashcode, error))
            status = EnumResponseStatus.RESPONSE_EXCEPTION_HAPPENED
        finally:
            # failed operation
            if EnumResponseStatus.RESPONSE_OK != status:
                # send error response
                HtlcResponsesMessage.send_error_response(
                    self.sender, self.receiver, self.channel_name,
                    self.asset_type, self.nonce, status)

                # delete some related resources
                self.rollback_resource(self.channel_name, self.nonce,
                                       self.payment, status.name)

        return