URI: 
       tlnpeer: distinguish local and remote pending updates - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit e475617b7566556b337ccdc12fca64be57787453
   DIR parent 459f9aaee70c258e8fe925b016ed2adcdc7307fa
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Wed, 13 Feb 2019 10:59:22 +0100
       
       lnpeer: distinguish local and remote pending updates
       
       Diffstat:
         M electrum/lnpeer.py                  |      38 ++++++++++++++++++-------------
       
       1 file changed, 22 insertions(+), 16 deletions(-)
       ---
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -77,13 +77,14 @@ class Peer(PrintError):
                self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_REQ
                self.attempted_route = {}
                self.orphan_channel_updates = OrderedDict()
       -        self.pending_updates = defaultdict(bool)
       +        self.remote_pending_updates = defaultdict(bool) # true if we sent updates that we have not commited yet
       +        self.local_pending_updates = defaultdict(bool) # true if we received updates that we have not commited yet
                self._local_changed_events = defaultdict(asyncio.Event)
                self._remote_changed_events = defaultdict(asyncio.Event)
        
            def send_message(self, message_name: str, **kwargs):
                assert type(message_name) is str
       -        #self.print_error("Sending '%s'"%message_name.upper())
       +        self.print_error("Sending '%s'"%message_name.upper())
                self.transport.send_bytes(encode_msg(message_name, **kwargs))
        
            async def initialize(self):
       t@@ -770,7 +771,7 @@ class Peer(PrintError):
                # process update_fail_htlc on channel
                chan = self.channels[channel_id]
                chan.receive_fail_htlc(htlc_id)
       -        self.pending_updates[chan] = True
       +        self.local_pending_updates[chan] = True
                local_ctn = chan.get_current_ctn(LOCAL)
                asyncio.ensure_future(self._on_update_fail_htlc(chan, htlc_id, local_ctn))
        
       t@@ -821,12 +822,13 @@ class Peer(PrintError):
                        self.network.path_finder.blacklist.add(short_chan_id)
        
            def maybe_send_commitment(self, chan: Channel):
       -        if not self.pending_updates[chan]:
       +        if not self.local_pending_updates[chan] and not self.remote_pending_updates[chan]:
                    return
                self.print_error('send_commitment')
                sig_64, htlc_sigs = chan.sign_next_commitment()
                self.send_message("commitment_signed", channel_id=chan.channel_id, signature=sig_64, num_htlcs=len(htlc_sigs), htlc_signature=b"".join(htlc_sigs))
       -        self.pending_updates[chan] = False
       +        self.local_pending_updates[chan] = False
       +        self.remote_pending_updates[chan] = False
        
            async def await_remote(self, chan: Channel, ctn: int):
                self.maybe_send_commitment(chan)
       t@@ -862,7 +864,7 @@ class Peer(PrintError):
                                  amount_msat=amount_msat,
                                  payment_hash=payment_hash,
                                  onion_routing_packet=onion.to_bytes())
       -        self.pending_updates[chan] = True
       +        self.remote_pending_updates[chan] = True
                await self.await_remote(chan, remote_ctn)
                return UpdateAddHtlc(**htlc, htlc_id=htlc_id)
        
       t@@ -891,7 +893,7 @@ class Peer(PrintError):
                preimage = update_fulfill_htlc_msg["payment_preimage"]
                htlc_id = int.from_bytes(update_fulfill_htlc_msg["id"], "big")
                chan.receive_htlc_settle(preimage, htlc_id)
       -        self.pending_updates[chan] = True
       +        self.local_pending_updates[chan] = True
                local_ctn = chan.get_current_ctn(LOCAL)
                asyncio.ensure_future(self._on_update_fulfill_htlc(chan, htlc_id, preimage, local_ctn))
        
       t@@ -923,15 +925,18 @@ class Peer(PrintError):
                # add htlc
                htlc = {'amount_msat': amount_msat_htlc, 'payment_hash':payment_hash, 'cltv_expiry':cltv_expiry}
                htlc_id = chan.receive_htlc(htlc)
       +        self.local_pending_updates[chan] = True
                local_ctn = chan.get_current_ctn(LOCAL)
       +        remote_ctn = chan.get_current_ctn(REMOTE)
                if processed_onion.are_we_final:
       -            asyncio.ensure_future(self._maybe_fulfill_htlc(chan, local_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion))
       +            asyncio.ensure_future(self._maybe_fulfill_htlc(chan, local_ctn, remote_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion))
                else:
       -            asyncio.ensure_future(self._maybe_forward_htlc(chan, local_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion))
       +            asyncio.ensure_future(self._maybe_forward_htlc(chan, local_ctn, remote_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion))
        
            @log_exceptions 
       -    async def _maybe_forward_htlc(self, chan, local_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion):
       +    async def _maybe_forward_htlc(self, chan, local_ctn, remote_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion):
                await self.await_local(chan, local_ctn)
       +        await self.await_remote(chan, remote_ctn)
                # Forward HTLC
                # FIXME: this is not robust to us going offline before payment is fulfilled
                dph = processed_onion.hop_data.per_hop
       t@@ -957,7 +962,7 @@ class Peer(PrintError):
                    payment_hash=payment_hash,
                    onion_routing_packet=processed_onion.next_packet.to_bytes()
                )
       -        next_peer.pending_updates[next_chan] = True
       +        next_peer.remote_pending_updates[next_chan] = True
                await next_peer.await_remote(next_chan, next_remote_ctn)
                # wait until we get paid
                preimage = await next_peer.payment_preimages[payment_hash].get()
       t@@ -966,8 +971,9 @@ class Peer(PrintError):
                self.print_error("htlc forwarded successfully")
        
            @log_exceptions
       -    async def _maybe_fulfill_htlc(self, chan, local_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion):
       +    async def _maybe_fulfill_htlc(self, chan, local_ctn, remote_ctn, htlc_id, htlc, payment_hash, cltv_expiry, amount_msat_htlc, processed_onion):
                await self.await_local(chan, local_ctn)
       +        await self.await_remote(chan, remote_ctn)
                try:
                    preimage, invoice = self.lnworker.get_invoice(payment_hash)
                except UnknownPaymentHash:
       t@@ -1009,7 +1015,7 @@ class Peer(PrintError):
                                  channel_id=chan.channel_id,
                                  id=htlc_id,
                                  payment_preimage=preimage)
       -        self.pending_updates[chan] = True
       +        self.remote_pending_updates[chan] = True
                await self.await_remote(chan, remote_ctn)
                self.network.trigger_callback('ln_message', self.lnworker, 'Payment received', htlc_id)
        
       t@@ -1024,7 +1030,7 @@ class Peer(PrintError):
                                  id=htlc_id,
                                  len=len(error_packet),
                                  reason=error_packet)
       -        self.pending_updates[chan] = True
       +        self.remote_pending_updates[chan] = True
                await self.await_remote(chan, remote_ctn)
        
            def on_revoke_and_ack(self, payload):
       t@@ -1041,7 +1047,7 @@ class Peer(PrintError):
                feerate =int.from_bytes(payload["feerate_per_kw"], "big")
                chan = self.channels[channel_id]
                chan.update_fee(feerate, False)
       -        self.pending_updates[chan] = True
       +        self.local_pending_updates[chan] = True
        
            async def bitcoin_fee_update(self, chan: Channel):
                """
       t@@ -1065,7 +1071,7 @@ class Peer(PrintError):
                self.send_message("update_fee",
                                  channel_id=chan.channel_id,
                                  feerate_per_kw=feerate_per_kw)
       -        self.pending_updates[chan] = True
       +        self.remote_pending_updates[chan] = True
                await self.await_remote(chan, remote_ctn)
        
            def on_closing_signed(self, payload):