URI: 
       tlnworker: return error reason in await_payment - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit d6d644190e8f922cb98b9a5e9b40fb36fa021ff7
   DIR parent 0557738a6bc5f399178063b16776c405a7b905dd
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri, 11 Oct 2019 13:37:54 +0200
       
       lnworker: return error reason in await_payment
       
       Diffstat:
         M electrum/lnpeer.py                  |      15 ++++++++-------
         M electrum/lnworker.py                |      23 +++++++++++++----------
       
       2 files changed, 21 insertions(+), 17 deletions(-)
       ---
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -1091,19 +1091,20 @@ class Peer(Logger):
            def on_update_fail_htlc(self, payload):
                channel_id = payload["channel_id"]
                htlc_id = int.from_bytes(payload["id"], "big")
       +        reason = payload["reason"]
                chan = self.channels[channel_id]
                self.logger.info(f"on_update_fail_htlc. chan {chan.short_channel_id}. htlc_id {htlc_id}")
                chan.receive_fail_htlc(htlc_id)
                local_ctn = chan.get_latest_ctn(LOCAL)
                asyncio.ensure_future(self._handle_error_code_from_failed_htlc(payload, channel_id, htlc_id))
       -        asyncio.ensure_future(self._on_update_fail_htlc(channel_id, htlc_id, local_ctn))
       +        asyncio.ensure_future(self._on_update_fail_htlc(channel_id, htlc_id, local_ctn, reason))
        
            @log_exceptions
       -    async def _on_update_fail_htlc(self, channel_id, htlc_id, local_ctn):
       +    async def _on_update_fail_htlc(self, channel_id, htlc_id, local_ctn, reason):
                chan = self.channels[channel_id]
                await self.await_local(chan, local_ctn)
                payment_hash = chan.get_payment_hash(htlc_id)
       -        self.lnworker.payment_sent(payment_hash, False)
       +        self.lnworker.payment_failed(payment_hash, reason)
        
            @log_exceptions
            async def _handle_error_code_from_failed_htlc(self, payload, channel_id, htlc_id):
       t@@ -1273,7 +1274,7 @@ class Peer(Logger):
            @log_exceptions
            async def _on_update_fulfill_htlc(self, chan, local_ctn, payment_hash):
                await self.await_local(chan, local_ctn)
       -        self.lnworker.payment_sent(payment_hash, True)
       +        self.lnworker.payment_sent(payment_hash)
        
            def on_update_fail_malformed_htlc(self, payload):
                self.logger.info(f"on_update_fail_malformed_htlc. error {payload['data'].decode('ascii')}")
       t@@ -1391,13 +1392,13 @@ class Peer(Logger):
                    onion_routing_packet=processed_onion.next_packet.to_bytes()
                )
                await next_peer.await_remote(next_chan, next_remote_ctn)
       -        success, preimage = await self.lnworker.await_payment(next_htlc.payment_hash)
       +        success, preimage, reason = await self.lnworker.await_payment(next_htlc.payment_hash)
                if success:
                    await self._fulfill_htlc(chan, htlc.htlc_id, preimage)
                    self.logger.info("htlc forwarded successfully")
                else:
       -            self.logger.info("htlc not fulfilled")
       -            # TODO: Read error code and forward it, as follows:
       +            # TODO: test this
       +            self.logger.info(f"forwarded htlc has failed, {reason}")
                    await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason)
        
            @log_exceptions
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -862,7 +862,8 @@ class LNWallet(LNWorker):
                for i in range(attempts):
                    route = await self._create_route_from_invoice(decoded_invoice=lnaddr)
                    self.network.trigger_callback('payment_status', key, 'progress', i)
       -            if await self._pay_to_route(route, lnaddr):
       +            success, preimage, reason = await self._pay_to_route(route, lnaddr)
       +            if success:
                        return True
                return False
        
       t@@ -876,8 +877,7 @@ class LNWallet(LNWorker):
                peer = self.peers[route[0].node_id]
                htlc = await peer.pay(route, chan, int(lnaddr.amount * COIN * 1000), lnaddr.paymenthash, lnaddr.get_min_final_cltv_expiry())
                self.network.trigger_callback('htlc_added', htlc, lnaddr, SENT)
       -        success, preimage = await self.await_payment(lnaddr.paymenthash)
       -        return success
       +        return await self.await_payment(lnaddr.paymenthash)
        
            @staticmethod
            def _check_invoice(invoice, amount_sat=None):
       t@@ -1028,10 +1028,9 @@ class LNWallet(LNWorker):
                return status
        
            async def await_payment(self, payment_hash):
       -        success = await self.pending_payments[payment_hash]
       +        success, preimage, reason = await self.pending_payments[payment_hash]
                self.pending_payments.pop(payment_hash)
       -        preimage = self.get_preimage(payment_hash)
       -        return success, preimage
       +        return success, preimage, reason
        
            def set_payment_status(self, payment_hash: bytes, status):
                try:
       t@@ -1042,10 +1041,14 @@ class LNWallet(LNWorker):
                info = info._replace(status=status)
                self.save_payment_info(info)
        
       -    def payment_sent(self, payment_hash: bytes, success):
       -        status = PR_PAID if success  else PR_UNPAID
       -        self.set_payment_status(payment_hash, status)
       -        self.pending_payments[payment_hash].set_result(success)
       +    def payment_failed(self, payment_hash: bytes, reason):
       +        self.set_payment_status(payment_hash, PR_UNPAID)
       +        self.pending_payments[payment_hash].set_result((False, None, reason))
       +
       +    def payment_sent(self, payment_hash: bytes):
       +        self.set_payment_status(payment_hash, PR_PAID)
       +        preimage = self.get_preimage(payment_hash)
       +        self.pending_payments[payment_hash].set_result((True, preimage, None))
        
            def payment_received(self, payment_hash: bytes):
                self.set_payment_status(payment_hash, PR_PAID)