Browse Source

kivy: add option to request force-close

patch-4
ThomasV 4 years ago
parent
commit
1a49fd440d
  1. 30
      electrum/gui/kivy/uix/dialogs/lightning_channels.py
  2. 13
      electrum/gui/messages.py
  3. 5
      electrum/gui/qt/channels_list.py

30
electrum/gui/kivy/uix/dialogs/lightning_channels.py

@ -15,8 +15,10 @@ from .question import Question
from electrum.transaction import PartialTxOutput, Transaction from electrum.transaction import PartialTxOutput, Transaction
from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates, format_fee_satoshis, quantize_feerate from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates, format_fee_satoshis, quantize_feerate
from electrum.lnutil import ln_dummy_address from electrum.lnutil import ln_dummy_address
from electrum.gui import messages
from .qr_dialog import QRDialog from .qr_dialog import QRDialog
from .choice_dialog import ChoiceDialog
if TYPE_CHECKING: if TYPE_CHECKING:
from ...main_window import ElectrumWindow from ...main_window import ElectrumWindow
@ -437,7 +439,7 @@ class ChannelBackupPopup(Popup, Logger):
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.request_force_close_from_backup(self.chan.channel_id), loop) coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.request_force_close_from_backup(self.chan.channel_id), loop)
try: try:
coro.result(5) coro.result(5)
self.app.show_info(_('Channel closed')) self.app.show_info(_('Request sent'))
except Exception as e: except Exception as e:
self.logger.exception("Could not close channel") self.logger.exception("Could not close channel")
self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == '' self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == ''
@ -490,16 +492,26 @@ class ChannelDetailsPopup(Popup, Logger):
self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(chan.node_id) else _('Warning') + ': ' + msg self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(chan.node_id) else _('Warning') + ': ' + msg
def close(self): def close(self):
Question(_('Close channel?'), self._close).open() dialog = ChoiceDialog(
title=_('Close channel'),
def _close(self, b): choices={0:_('Cooperative close'), 1:_('Request force-close')}, key=0,
if not b: callback=self._close,
return description=_(messages.MSG_REQUEST_FORCE_CLOSE),
keep_choice_order=True)
dialog.open()
def _close(self, choice):
loop = self.app.wallet.network.asyncio_loop loop = self.app.wallet.network.asyncio_loop
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.close_channel(self.chan.channel_id), loop) if choice == 1:
coro = self.app.wallet.lnworker.request_force_close_from_backup(self.chan.channel_id)
msg = _('Request sent')
else:
coro = self.app.wallet.lnworker.close_channel(self.chan.channel_id)
msg = _('Channel closed')
f = asyncio.run_coroutine_threadsafe(coro, loop)
try: try:
coro.result(5) f.result(5)
self.app.show_info(_('Channel closed')) self.app.show_info(msg)
except Exception as e: except Exception as e:
self.logger.exception("Could not close channel") self.logger.exception("Could not close channel")
self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == '' self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == ''

13
electrum/gui/messages.py

@ -1,14 +1,11 @@
# note: qt and kivy use different i18n methods # note: qt and kivy use different i18n methods
MSG_RECOVERABLE_CHANNELS = """ MSG_RECOVERABLE_CHANNELS = """
Add extra data to your channel funding transactions, so that a static backup can be Add extra data to your channel funding transactions, so that a static backup can be recovered from your seed.
recovered from your seed.
Note that static backups only allow you to request a force-close with the remote node. Note that static backups only allow you to request a force-close with the remote node. This assumes that the remote node is still online, did not lose its data, and accepts to force close the channel.
This assumes that the remote node is still online, did not lose its data, and accepts
to force close the channel.
If this is enabled, other nodes cannot open a channel to you. Channel recovery data If this is enabled, other nodes cannot open a channel to you. Channel recovery data is encrypted, so that only your wallet can decrypt it. However, blockchain analysis will be able to tell that the transaction was probably created by Electrum.
is encrypted, so that only your wallet can decrypt it. However, blockchain analysis
will be able to tell that the transaction was probably created by Electrum.
""" """
MSG_REQUEST_FORCE_CLOSE = """If you choose to request force-close, your node will pretend that it has lost its data and ask the remote node to broadcast their latest state. Doing so from time to time helps make sure that nodes are honest, because your node can punish them if they broadcast a revoked state."""

5
electrum/gui/qt/channels_list.py

@ -16,6 +16,7 @@ from electrum.wallet import Abstract_Wallet
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id, LN_MAX_FUNDING_SAT from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id, LN_MAX_FUNDING_SAT
from electrum.lnworker import LNWallet from electrum.lnworker import LNWallet
from electrum import ecc from electrum import ecc
from electrum.gui import messages
from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButton, from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButton,
EnterButton, WaitingDialog, MONOSPACE_FONT, ColorScheme) EnterButton, WaitingDialog, MONOSPACE_FONT, ColorScheme)
@ -111,9 +112,7 @@ class ChannelsList(MyTreeView):
self.is_force_close = False self.is_force_close = False
msg = _('Close channel?') msg = _('Close channel?')
force_cb = QCheckBox('Request force close from remote peer') force_cb = QCheckBox('Request force close from remote peer')
tooltip = _( tooltip = _(messages.MSG_REQUEST_FORCE_CLOSE)
'If you check this option, your node will pretend that it has lost its data and ask the remote node to broadcast their latest state. '
'Doing so from time to time helps make sure that nodes are honest, because your node can punish them if they broadcast a revoked state.')
tooltip = '<qt>' + tooltip + '</qt>' # rich text is word wrapped tooltip = '<qt>' + tooltip + '</qt>' # rich text is word wrapped
def on_checked(b): def on_checked(b):
self.is_force_close = bool(b) self.is_force_close = bool(b)

Loading…
Cancel
Save