From 0efe7e9bc81d376b8faa8f2e9b7edbe2d10fec69 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Fri, 10 Jan 2025 16:18:57 +0100 Subject: [PATCH] swaps: make the zeroconf option non-persisted Since we allow swaps with random servers, we should not persist that setting. --- electrum/gui/qt/swap_dialog.py | 23 +++++++++++++++++------ electrum/simple_config.py | 7 ------- electrum/submarine_swaps.py | 7 +++++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/electrum/gui/qt/swap_dialog.py b/electrum/gui/qt/swap_dialog.py index e14636a5d..f36ba704e 100644 --- a/electrum/gui/qt/swap_dialog.py +++ b/electrum/gui/qt/swap_dialog.py @@ -44,8 +44,8 @@ class SwapDialog(WindowModalDialog, QtEventListener): self.is_reverse = is_reverse if is_reverse is not None else True vbox = QVBoxLayout(self) toolbar, menu = create_toolbar_with_menu(self.config, '') - menu.addConfig( - self.config.cv.LIGHTNING_ALLOW_INSTANT_SWAPS, + menu.addToggle( + _('Zeroconf swap'), self.toggle_zeroconf ).setEnabled(self.lnworker.can_have_recoverable_channels()) if not self.config.SWAPSERVER_URL: menu.addAction(_('Choose swap server'), lambda: self.window.choose_swapserver_dialog(transport)) @@ -62,6 +62,7 @@ class SwapDialog(WindowModalDialog, QtEventListener): # send_follows is used to know whether the send amount field / receive # amount field should be adjusted after the fee slider was moved self.send_follows = False + self.zeroconf = False self.send_amount_e.follows = False self.recv_amount_e.follows = False self.toggle_button.clicked.connect(self.toggle_direction) @@ -108,6 +109,15 @@ class SwapDialog(WindowModalDialog, QtEventListener): self.window.gui_object.timer.timeout.connect(self.timer_actions) self.register_callbacks() + def toggle_zeroconf(self): + self.zeroconf = not self.zeroconf + if self.zeroconf: + msg = "\n\n".join([ + "Zero-confirmation swap: Your wallet will not wait until the funding transaction is confirmed.", + "Note that this option is risky: the server can steal your funds if they double-spend the funding transaction." + ]) + self.window.show_warning(msg) + def closeEvent(self, event): self.unregister_callbacks() event.accept() @@ -255,10 +265,11 @@ class SwapDialog(WindowModalDialog, QtEventListener): return sm = self.swap_manager coro = sm.reverse_swap( - transport, - lightning_amount_sat=lightning_amount, - expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_claim_fee(), - ) + transport, + lightning_amount_sat=lightning_amount, + expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_claim_fee(), + zeroconf=self.zeroconf, + ) # we must not leave the context, so we use run_couroutine_dialog funding_txid = self.window.run_coroutine_dialog(coro, _('Initiating swap...')) self.window.on_swap_result(funding_txid, is_reverse=True) diff --git a/electrum/simple_config.py b/electrum/simple_config.py index eefa8e72f..fbef1aa2a 100644 --- a/electrum/simple_config.py +++ b/electrum/simple_config.py @@ -1016,13 +1016,6 @@ Downloading the network gossip uses quite some bandwidth and storage, and is not 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. 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."""), - ) - LIGHTNING_ALLOW_INSTANT_SWAPS = ConfigVar( - 'allow_instant_swaps', default=False, type_=bool, - short_desc=lambda: _("Allow instant swaps"), - long_desc=lambda: _("""If this option is checked, your client will complete reverse swaps before the funding transaction is confirmed. - -Note you are at risk of losing the funds in the swap, if the funding transaction never confirms."""), ) LIGHTNING_TO_SELF_DELAY_CSV = ConfigVar('lightning_to_self_delay', default=7 * 144, type_=int) LIGHTNING_MAX_FUNDING_SAT = ConfigVar('lightning_max_funding_sat', default=LN_MAX_FUNDING_SAT_LEGACY, type_=int) diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py index 1704d2254..b9cd0f80f 100644 --- a/electrum/submarine_swaps.py +++ b/electrum/submarine_swaps.py @@ -152,6 +152,7 @@ class SwapData(StoredObject): _funding_prevout = None # type: Optional[TxOutpoint] # for RBF _payment_hash = None + _zeroconf = False @property def payment_hash(self) -> bytes: @@ -351,7 +352,7 @@ class SwapManager(Logger): self.lnwatcher.remove_callback(swap.lockup_address) swap.is_redeemed = True elif spent_height == TX_HEIGHT_LOCAL: - if funding_height.conf > 0 or (swap.is_reverse and self.wallet.config.LIGHTNING_ALLOW_INSTANT_SWAPS): + if funding_height.conf > 0 or (swap.is_reverse and swap._zeroconf): tx = self.lnwatcher.adb.get_transaction(txin.spent_txid) try: await self.network.broadcast_transaction(tx) @@ -428,7 +429,7 @@ class SwapManager(Logger): self.logger.info(f'adding claim tx {tx.txid()}') self.wallet.adb.add_transaction(tx) swap.spending_txid = tx.txid() - if funding_height.conf > 0 or (swap.is_reverse and self.wallet.config.LIGHTNING_ALLOW_INSTANT_SWAPS): + if funding_height.conf > 0 or (swap.is_reverse and swap._zeroconf): try: await self.network.broadcast_transaction(tx) except TxBroadcastError: @@ -823,6 +824,7 @@ class SwapManager(Logger): *, lightning_amount_sat: int, expected_onchain_amount_sat: int, + zeroconf: bool=False, channels: Optional[Sequence['Channel']] = None, ) -> Optional[str]: """send on Lightning, receive on-chain @@ -903,6 +905,7 @@ class SwapManager(Logger): prepay_hash=prepay_hash, onchain_amount_sat=onchain_amount, lightning_amount_sat=lightning_amount_sat) + swap._zeroconf = zeroconf # initiate fee payment. if fee_invoice: asyncio.ensure_future(self.lnworker.pay_invoice(fee_invoice))