URI: 
       tPropagate exceptions raise by force_close to the GUI. Define 'try_force_closing' for cases where we do not want exceptions to be raised. - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 888a6d726e4599e8efb9a15fe4f76c15b3af69c1
   DIR parent 15fb8c04158c563f0d010db1b5b83b39f4464b7f
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri,  6 Mar 2020 12:17:26 +0100
       
       Propagate exceptions raise by force_close to the GUI.
       Define 'try_force_closing' for cases where we do not
       want exceptions to be raised.
       
       Diffstat:
         M electrum/lnchannel.py               |       1 +
         M electrum/lnpeer.py                  |       6 +++---
         M electrum/lnworker.py                |      12 ++++++++++--
       
       3 files changed, 14 insertions(+), 5 deletions(-)
       ---
   DIR diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py
       t@@ -98,6 +98,7 @@ state_transitions = [
            (cs.OPEN, cs.CLOSED),
            (cs.CLOSING, cs.CLOSING), # if we reestablish
            (cs.CLOSING, cs.CLOSED),
       +    (cs.FORCE_CLOSING, cs.FORCE_CLOSING), # allow multiple attempts
            (cs.FORCE_CLOSING, cs.CLOSED),
            (cs.FORCE_CLOSING, cs.REDEEMED),
            (cs.CLOSED, cs.REDEEMED),
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -869,11 +869,11 @@ class Peer(Logger):
                    return
                elif we_are_ahead:
                    self.logger.warning(f"channel_reestablish ({chan.get_id_for_log()}): we are ahead of remote! trying to force-close.")
       -            await self.lnworker.force_close_channel(chan_id)
       +            await self.lnworker.try_force_closing(chan_id)
                    return
                elif self.lnworker.wallet.is_lightning_backup():
                    self.logger.warning(f"channel_reestablish ({chan.get_id_for_log()}): force-closing because we are a recent backup")
       -            await self.lnworker.force_close_channel(chan_id)
       +            await self.lnworker.try_force_closing(chan_id)
                    return
        
                chan.peer_state = peer_states.GOOD
       t@@ -1106,7 +1106,7 @@ class Peer(Logger):
                if chan.get_state() != channel_states.OPEN:
                    raise RemoteMisbehaving(f"received update_add_htlc while chan.get_state() != OPEN. state was {chan.get_state()}")
                if cltv_expiry > bitcoin.NLOCKTIME_BLOCKHEIGHT_MAX:
       -            asyncio.ensure_future(self.lnworker.force_close_channel(channel_id))
       +            asyncio.ensure_future(self.lnworker.try_force_closing(channel_id))
                    raise RemoteMisbehaving(f"received update_add_htlc with cltv_expiry > BLOCKHEIGHT_MAX. value was {cltv_expiry}")
                # add htlc
                htlc = UpdateAddHtlc(
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -732,7 +732,7 @@ class LNWallet(LNWorker):
        
                if chan.get_state() == channel_states.OPEN and self.should_channel_be_closed_due_to_expiring_htlcs(chan):
                    self.logger.info(f"force-closing due to expiring htlcs")
       -            await self.force_close_channel(chan.channel_id)
       +            await self.try_force_closing(chan.channel_id)
                    return
        
                if chan.get_state() == channel_states.OPENING:
       t@@ -1297,11 +1297,19 @@ class LNWallet(LNWorker):
                return await peer.close_channel(chan_id)
        
            async def force_close_channel(self, chan_id):
       +        # returns txid or raises
       +        chan = self.channels[chan_id]
       +        tx = chan.force_close_tx()
       +        txid = await self.network.broadcast_transaction(tx)
       +        chan.set_state(channel_states.FORCE_CLOSING)
       +        return txid
       +
       +    async def try_force_closing(self, chan_id):
       +        # fails silently but sets the state, so that we will retry later
                chan = self.channels[chan_id]
                tx = chan.force_close_tx()
                chan.set_state(channel_states.FORCE_CLOSING)
                await self.network.try_broadcasting(tx, 'force-close')
       -        return tx.txid()
        
            def remove_channel(self, chan_id):
                chan = self.channels[chan_id]