Skip to content

Commit ab388b5

Browse files
committed
lnsweep: refactor: maybe_reveal_preimage_for_htlc
1 parent 49d9523 commit ab388b5

File tree

1 file changed

+41
-33
lines changed

1 file changed

+41
-33
lines changed

electrum/lnsweep.py

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
482500
def 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

Comments
 (0)