Browse Source

Reverse swaps: Wait until funding tx is confirmed

- override with allow_instant_swaps option (Qt)
patch-4
ThomasV 3 years ago
parent
commit
f01197b6b5
  1. 3
      electrum/address_synchronizer.py
  2. 12
      electrum/gui/qt/settings_dialog.py
  3. 5
      electrum/lnworker.py
  4. 20
      electrum/submarine_swaps.py

3
electrum/address_synchronizer.py

@ -239,6 +239,9 @@ class AddressSynchronizer(Logger):
conflicting_txns -= {tx_hash}
return conflicting_txns
def get_transaction(self, txid: str) -> Transaction:
return self.db.get_transaction(txid)
def add_transaction(self, tx: Transaction, *, allow_unrelated=False) -> bool:
"""
Returns whether the tx was successfully added to the wallet history.

12
electrum/gui/qt/settings_dialog.py

@ -158,6 +158,18 @@ class SettingsDialog(WindowModalDialog):
trampoline_cb.stateChanged.connect(on_trampoline_checked)
lightning_widgets.append((trampoline_cb, None))
help_instant_swaps = ' '.join([
_("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.")
])
instant_swaps_cb = QCheckBox(_("Allow instant swaps"))
instant_swaps_cb.setToolTip(messages.to_rtf(help_instant_swaps))
trampoline_cb.setChecked(not bool(self.config.get('allow_instant_swaps', False)))
def on_instant_swaps_checked(allow_instant_swaps):
self.config.set_key('allow_instant_swaps', bool(allow_instant_swaps))
instant_swaps_cb.stateChanged.connect(on_instant_swaps_checked)
lightning_widgets.append((instant_swaps_cb, None))
help_remote_wt = ' '.join([
_("A watchtower is a daemon that watches your channels and prevents the other party from stealing funds by broadcasting an old state."),
_("If you have private a watchtower, enter its URL here."),

5
electrum/lnworker.py

@ -908,7 +908,10 @@ class LNWallet(LNWorker):
amount_msat = 0
label = 'Reverse swap' if swap.is_reverse else 'Forward swap'
delta = current_height - swap.locktime
if not swap.is_redeemed and swap.spending_txid is None and delta < 0:
tx_height = self.lnwatcher.get_tx_height(swap.funding_txid)
if swap.is_reverse and tx_height.height <=0:
label += ' (%s)' % _('waiting for funding tx confirmation')
if not swap.is_reverse and not swap.is_redeemed and swap.spending_txid is None and delta < 0:
label += f' (refundable in {-delta} blocks)' # fixme: only if unspent
out[txid] = {
'txid': txid,

20
electrum/submarine_swaps.py

@ -20,6 +20,7 @@ from .logging import Logger
from .lnutil import hex_to_bytes
from .json_db import StoredObject
from . import constants
from .address_synchronizer import TX_HEIGHT_LOCAL
if TYPE_CHECKING:
from .network import Network
@ -176,10 +177,17 @@ class SwapManager(Logger):
spent_height = txin.spent_height
if spent_height is not None:
swap.spending_txid = txin.spent_txid
if spent_height > 0 and current_height - spent_height > REDEEM_AFTER_DOUBLE_SPENT_DELAY:
self.logger.info(f'stop watching swap {swap.lockup_address}')
self.lnwatcher.remove_callback(swap.lockup_address)
swap.is_redeemed = True
if spent_height > 0:
if current_height - spent_height > REDEEM_AFTER_DOUBLE_SPENT_DELAY:
self.logger.info(f'stop watching swap {swap.lockup_address}')
self.lnwatcher.remove_callback(swap.lockup_address)
swap.is_redeemed = True
elif spent_height == TX_HEIGHT_LOCAL:
if txin.block_height > 0 or self.wallet.config.get('allow_instant_swaps', False):
tx = self.lnwatcher.get_transaction(txin.spent_txid)
self.logger.info(f'broadcasting tx {txin.spent_txid}')
await self.network.broadcast_transaction(tx)
# already in mempool
continue
if not swap.is_reverse and delta < 0:
# too early for refund
@ -206,7 +214,9 @@ class SwapManager(Logger):
locktime=locktime,
)
self.sign_tx(tx, swap)
await self.network.broadcast_transaction(tx)
self.logger.info(f'adding claim tx {tx.txid()}')
self.wallet.add_transaction(tx)
self.lnwatcher.add_transaction(tx)
def get_claim_fee(self):
return self.wallet.config.estimate_fee(136, allow_fallback_to_static_rates=True)

Loading…
Cancel
Save