From ec97d623a559d7f3b94d3c113487569c36754469 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Fri, 1 Mar 2019 19:32:49 +0100 Subject: [PATCH] force-close channel if unfulfilled htlc is close to cltv expiry --- electrum/lnchannel.py | 4 ++++ electrum/lnworker.py | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py index e27ec3eb2..e42b037c7 100644 --- a/electrum/lnchannel.py +++ b/electrum/lnchannel.py @@ -603,6 +603,10 @@ class Channel(PrintError): sub = LOCAL if direction == SENT else REMOTE return htlcsum(self.hm.settled_htlcs_by(sub, self.config[sub].ctn)) + def get_unfulfilled_htlcs(self): + log = self.hm.log[REMOTE] + return [v for x,v in log['adds'].items() if x not in log['settles']] + def settle_htlc(self, preimage, htlc_id): """ SettleHTLC attempts to settle an existing outstanding received HTLC. diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 38d2b1d16..5ade6e62b 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -368,6 +368,16 @@ class LNWorker(PrintError): else: self.wallet.add_future_tx(e_tx, remaining) + def is_dangerous(self, chan): + for x in chan.get_unfulfilled_htlcs(): + dust_limit = chan.config[REMOTE].dust_limit_sat * 1000 + delay = x.cltv_expiry - self.network.get_local_height() + if x.amount_msat > 10 * dust_limit and delay < 3: + self.print_error('htlc is dangerous') + return True + else: + self.print_error('htlc is not dangerous', delay) + return False @log_exceptions async def on_network_update(self, event, *args): @@ -381,6 +391,9 @@ class LNWorker(PrintError): if args[0] != lnwatcher: return for chan in channels: + if chan.get_state() in ["OPEN", "DISCONNECTED"] and self.is_dangerous(chan): + await self.force_close_channel(chan.channel_id) + continue if chan.short_channel_id is None: self.save_short_chan_id(chan) if chan.get_state() == "OPENING" and chan.short_channel_id: