1
0

submarine swaps: fail received HTLCs of normal swap htlcs if

the swap is still unfunded and the refund delay has expired.
This commit is contained in:
ThomasV
2023-09-08 14:44:52 +02:00
parent b0e18d8f8e
commit 136978e9d0
3 changed files with 42 additions and 19 deletions

View File

@@ -199,7 +199,7 @@ class SwapManager(Logger):
swap._payment_hash = payment_hash
self._add_or_reindex_swap(swap)
if not swap.is_reverse and not swap.is_redeemed:
self.lnworker.register_callback_for_hold_invoice(payment_hash, self.hold_invoice_callback)
self.lnworker.register_hold_invoice(payment_hash, self.hold_invoice_callback)
self.prepayments = {} # type: Dict[bytes, bytes] # fee_rhash -> rhash
for k, swap in self.swaps.items():
@@ -251,6 +251,15 @@ class SwapManager(Logger):
continue
await self.taskgroup.spawn(self.pay_invoice(key))
def fail_normal_swap(self, swap):
if swap.payment_hash in self.lnworker.hold_invoice_callbacks:
self.logger.info(f'failing normal swap {swap.payment_hash.hex()}')
self.lnworker.unregister_hold_invoice(swap.payment_hash)
payment_secret = self.lnworker.get_payment_secret(swap.payment_hash)
payment_key = swap.payment_hash + payment_secret
self.lnworker.fail_final_onion_forwarding(payment_key)
self.lnwatcher.remove_callback(swap.lockup_address)
@log_exceptions
async def _claim_swap(self, swap: SwapData) -> None:
assert self.network
@@ -260,10 +269,23 @@ class SwapManager(Logger):
current_height = self.network.get_local_height()
delta = current_height - swap.locktime
txos = self.lnwatcher.adb.get_addr_outputs(swap.lockup_address)
for txin in txos.values():
if swap.is_reverse and txin.value_sats() < swap.onchain_amount:
self.logger.info('amount too low, we should not reveal the preimage')
# amount too low, we must not reveal the preimage
continue
break
else:
# swap not funded.
if delta >= 0:
if not swap.is_reverse:
# we might have received HTLCs and double spent the funding tx
# in that case we need to fail the HTLCs
self.fail_normal_swap(swap)
txin = None
if txin:
# the swap is funded
swap.funding_txid = txin.prevout.txid.hex()
swap._funding_prevout = txin.prevout
self._add_or_reindex_swap(swap) # to update _swaps_by_funding_outpoint
@@ -298,42 +320,39 @@ class SwapManager(Logger):
else:
# refund tx
if spent_height > 0:
self.logger.info(f'found confirmed refund')
payment_secret = self.lnworker.get_payment_secret(swap.payment_hash)
payment_key = swap.payment_hash + payment_secret
self.lnworker.fail_final_onion_forwarding(payment_key)
self.fail_normal_swap(swap)
return
if delta < 0:
# too early for refund
continue
return
else:
if swap.preimage is None:
swap.preimage = self.lnworker.get_preimage(swap.payment_hash)
if swap.preimage is None:
if funding_conf <= 0:
continue
return
key = swap.payment_hash.hex()
if -delta <= MIN_LOCKTIME_DELTA:
if key in self.invoices_to_pay:
# fixme: should consider cltv of ln payment
self.logger.info(f'locktime too close {key} {delta}')
self.invoices_to_pay.pop(key, None)
continue
return
if key not in self.invoices_to_pay:
self.invoices_to_pay[key] = 0
continue
return
if self.network.config.TEST_SWAPSERVER_REFUND:
# for testing: do not create claim tx
continue
return
if spent_height is not None:
continue
return
try:
tx = self._create_and_sign_claim_tx(txin=txin, swap=swap, config=self.wallet.config)
except BelowDustLimit:
self.logger.info('utxo value below dust threshold')
continue
return
self.logger.info(f'adding claim tx {tx.txid()}')
self.wallet.adb.add_transaction(tx)
swap.spending_txid = tx.txid()
@@ -391,7 +410,7 @@ class SwapManager(Logger):
invoice=None,
prepay=True,
)
self.lnworker.register_callback_for_hold_invoice(payment_hash, self.hold_invoice_callback)
self.lnworker.register_hold_invoice(payment_hash, self.hold_invoice_callback)
return swap, invoice, prepay_invoice
def add_normal_swap(
@@ -652,7 +671,7 @@ class SwapManager(Logger):
data = json.loads(response)
async def callback(payment_hash):
await self.broadcast_funding_tx(swap, tx)
self.lnworker.register_callback_for_hold_invoice(payment_hash, callback)
self.lnworker.register_hold_invoice(payment_hash, callback)
# wait for funding tx
lnaddr = lndecode(invoice)
while swap.funding_txid is None and not lnaddr.is_expired():