Browse Source

lnchannel: do not expose COOP_CLOSE in the GUI if there are unsettled HTLCs

patch-4
ThomasV 3 years ago
parent
commit
dce39b38ce
  1. 14
      electrum/lnchannel.py
  2. 2
      electrum/lnpeer.py

14
electrum/lnchannel.py

@ -1193,6 +1193,9 @@ class Channel(AbstractChannel):
ctn = self.get_next_ctn(ctx_owner)
return htlcsum(self.hm.htlcs_by_direction(ctx_owner, direction, ctn).values())
def has_unsettled_htlcs(self) -> bool:
return len(self.hm.htlcs(LOCAL)) + len(self.hm.htlcs(REMOTE)) > 0
def available_to_spend(self, subject: HTLCOwner, *, strict: bool = True) -> int:
"""The usable balance of 'subject' in msat, after taking reserve and fees into
consideration. Note that fees (and hence the result) fluctuate even without user interaction.
@ -1535,10 +1538,17 @@ class Channel(AbstractChannel):
return tx
def get_close_options(self) -> Sequence[ChanCloseOption]:
# This method is used both in the GUI, and in lnpeer.schedule_force_closing
# in the latter case, the result does not depend on peer_state
ret = []
if not self.is_closed() and self.peer_state == PeerState.GOOD:
ret.append(ChanCloseOption.COOP_CLOSE)
ret.append(ChanCloseOption.REQUEST_REMOTE_FCLOSE)
# If there are unsettled HTLCs, althought is possible to cooperatively close,
# we choose not to expose that option in the GUI, because it is very likely
# that HTLCs will take a long time to settle (submarine swap, or stuck payment),
# and the close dialog would be taking a very long time to finish
if not self.has_unsettled_htlcs():
ret.append(ChanCloseOption.COOP_CLOSE)
ret.append(ChanCloseOption.REQUEST_REMOTE_FCLOSE)
if not self.is_closed() or self.get_state() == ChannelState.REQUESTED_FCLOSE:
ret.append(ChanCloseOption.LOCAL_FCLOSE)
assert not (self.get_state() == ChannelState.WE_ARE_TOXIC and ChanCloseOption.LOCAL_FCLOSE in ret), "local force-close unsafe if we are toxic"

2
electrum/lnpeer.py

@ -2016,7 +2016,7 @@ class Peer(Logger):
@log_exceptions
async def _shutdown(self, chan: Channel, payload, *, is_local: bool):
# wait until no HTLCs remain in either commitment transaction
while len(chan.hm.htlcs(LOCAL)) + len(chan.hm.htlcs(REMOTE)) > 0:
while chan.has_unsettled_htlcs():
self.logger.info(f'(chan: {chan.short_channel_id}) waiting for htlcs to settle...')
await asyncio.sleep(1)
# if no HTLCs remain, we must not send updates

Loading…
Cancel
Save