@@ -400,6 +400,7 @@ def txs_htlc(
400400 if actual_htlc_tx is None :
401401 name = 'offered-htlc' if htlc_direction == SENT else 'received-htlc'
402402 prevout = ctx .txid () + f':{ ctx_output_idx } '
403+ assert prevout not in txs
403404 txs [prevout ] = SweepInfo (
404405 name = name ,
405406 cltv_abs = htlc_tx .locktime ,
@@ -426,7 +427,9 @@ def txs_htlc(
426427 privkey = our_localdelayed_privkey .get_secret_bytes (),
427428 is_revocation = False ,
428429 ):
429- txs [actual_htlc_tx .txid () + f':{ output_idx } ' ] = SweepInfo (
430+ prevout = actual_htlc_tx .txid () + f':{ output_idx } '
431+ assert prevout not in txs
432+ txs [prevout ] = SweepInfo (
430433 name = f'second-stage-htlc:{ output_idx } ' ,
431434 cltv_abs = 0 ,
432435 txin = sweep_txin ,
@@ -449,23 +452,12 @@ def txs_htlc(
449452 preimage = None
450453 if actual_htlc_tx is None : # still in first-stage, so e.g. preimage not revealed yet
451454 if direction == RECEIVED :
452- if not chan .lnworker .is_complete_mpp (htlc .payment_hash ):
453- # - do not redeem this, it might publish the preimage of an incomplete MPP
454- # - OTOH maybe this chan just got closed, and we are still receiving new htlcs
455- # for this MPP set. So the MPP set might still transition to complete!
456- # The MPP_TIMEOUT is only around 2 minutes, so this window is short.
457- # The default keep_watching logic in lnwatcher is sufficient to call us again.
458- continue
459- if htlc .payment_hash in chan .lnworker .dont_settle_htlcs :
460- prevout = ctx .txid () + ':%d' % ctx_output_idx
461- txs [prevout ] = KeepWatchingTXO (
462- name = f"our_ctx_htlc_{ ctx_output_idx } _for_hold_invoice" ,
463- until_height = htlc .cltv_abs ,
464- )
465- continue
466- preimage = chan .lnworker .get_preimage (htlc .payment_hash )
455+ preimage = _maybe_reveal_preimage_for_htlc (
456+ chan = chan , htlc = htlc , txs = txs ,
457+ prevout = ctx .txid () + ':%d' % ctx_output_idx ,
458+ sweep_info_name = f"our_ctx_htlc_{ ctx_output_idx } _for_hold_invoice" ,
459+ )
467460 if not preimage :
468- # we might not have the preimage if this is a hold invoice
469461 continue
470462 try :
471463 txs_htlc (
@@ -479,6 +471,32 @@ def txs_htlc(
479471 return txs
480472
481473
474+ def _maybe_reveal_preimage_for_htlc (
475+ * ,
476+ chan : 'AbstractChannel' ,
477+ htlc : 'UpdateAddHtlc' ,
478+ txs : Dict [str , MaybeSweepInfo ], # mutated in-place!
479+ prevout : str ,
480+ sweep_info_name : str ,
481+ ) -> Optional [bytes ]:
482+ """Given a Remote-added-HTLC, return the preimage if it's okay to reveal it on-chain."""
483+ if not chan .lnworker .is_complete_mpp (htlc .payment_hash ):
484+ # - do not redeem this, it might publish the preimage of an incomplete MPP
485+ # - OTOH maybe this chan just got closed, and we are still receiving new htlcs
486+ # for this MPP set. So the MPP set might still transition to complete!
487+ # The MPP_TIMEOUT is only around 2 minutes, so this window is short.
488+ # The default keep_watching logic in lnwatcher is sufficient to call us again.
489+ return None
490+ if htlc .payment_hash in chan .lnworker .dont_settle_htlcs :
491+ txs [prevout ] = KeepWatchingTXO (
492+ name = sweep_info_name ,
493+ until_height = htlc .cltv_abs ,
494+ )
495+ return None
496+ preimage = chan .lnworker .get_preimage (htlc .payment_hash )
497+ return preimage
498+
499+
482500def extract_ctx_secrets (chan : 'Channel' , ctx : Transaction ):
483501 # note: the remote sometimes has two valid non-revoked commitment transactions,
484502 # either of which could be broadcast
@@ -739,6 +757,7 @@ def tx_htlc(
739757 cltv_abs = cltv_abs ,
740758 has_anchors = chan .has_anchors (),
741759 ):
760+ assert prevout not in txs
742761 txs [prevout ] = SweepInfo (
743762 name = f'their_ctx_htlc_{ ctx_output_idx } { "_for_revoked_ctx" if is_revocation else "" } ' ,
744763 cltv_abs = cltv_abs ,
@@ -760,23 +779,12 @@ def tx_htlc(
760779 preimage = None
761780 is_received_htlc = direction == RECEIVED
762781 if not is_received_htlc and not is_revocation :
763- if not chan .lnworker .is_complete_mpp (htlc .payment_hash ):
764- # - do not redeem this, it might publish the preimage of an incomplete MPP
765- # - OTOH maybe this chan just got closed, and we are still receiving new htlcs
766- # for this MPP set. So the MPP set might still transition to complete!
767- # The MPP_TIMEOUT is only around 2 minutes, so this window is short.
768- # The default keep_watching logic in lnwatcher is sufficient to call us again.
769- continue
770- if htlc .payment_hash in chan .lnworker .dont_settle_htlcs :
771- prevout = ctx .txid () + ':%d' % ctx_output_idx
772- txs [prevout ] = KeepWatchingTXO (
773- name = f"their_ctx_htlc_{ ctx_output_idx } _for_hold_invoice" ,
774- until_height = htlc .cltv_abs ,
775- )
776- continue
777- preimage = chan .lnworker .get_preimage (htlc .payment_hash )
782+ preimage = _maybe_reveal_preimage_for_htlc (
783+ chan = chan , htlc = htlc , txs = txs ,
784+ prevout = ctx .txid () + ':%d' % ctx_output_idx ,
785+ sweep_info_name = f"their_ctx_htlc_{ ctx_output_idx } _for_hold_invoice" ,
786+ )
778787 if not preimage :
779- # we might not have the preimage if this is a hold invoice
780788 continue
781789 tx_htlc (
782790 htlc = htlc ,
0 commit comments