commit ec97d623a559d7f3b94d3c113487569c36754469
parent 4dc6c6c82edbeb86357d55b507d4345b638757f8
Author: ThomasV <thomasv@electrum.org>
Date: Fri, 1 Mar 2019 19:32:49 +0100
force-close channel if unfulfilled htlc is close to cltv expiry
Diffstat:
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git 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
@@ -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: