88 "fmt"
99 "time"
1010
11+ "github.com/btcsuite/btcd/chaincfg/chainhash"
1112 "github.com/btcsuite/btcd/wire"
1213 "github.com/btcsuite/btcutil"
1314 "github.com/lightninglabs/lndclient"
@@ -56,6 +57,9 @@ type loopOutSwap struct {
5657
5758 htlc * swap.Htlc
5859
60+ // htlcTxHash is the confirmed htlc tx id.
61+ htlcTxHash * chainhash.Hash
62+
5963 swapPaymentChan chan lndclient.PaymentResult
6064 prePaymentChan chan lndclient.PaymentResult
6165}
@@ -210,6 +214,7 @@ func resumeLoopOutSwap(reqContext context.Context, cfg *swapConfig,
210214 } else {
211215 swap .state = lastUpdate .State
212216 swap .lastUpdateTime = lastUpdate .Time
217+ swap .htlcTxHash = lastUpdate .HtlcTxHash
213218 }
214219
215220 return swap , nil
@@ -376,6 +381,7 @@ func (s *loopOutSwap) executeSwap(globalCtx context.Context) error {
376381
377382 // Try to spend htlc and continue (rbf) until a spend has confirmed.
378383 spendDetails , err := s .waitForHtlcSpendConfirmed (globalCtx ,
384+ * htlcOutpoint ,
379385 func () error {
380386 return s .sweep (globalCtx , * htlcOutpoint , htlcValue )
381387 },
@@ -419,8 +425,9 @@ func (s *loopOutSwap) persistState(ctx context.Context) error {
419425 err := s .store .UpdateLoopOut (
420426 s .hash , updateTime ,
421427 loopdb.SwapStateData {
422- State : s .state ,
423- Cost : s .cost ,
428+ State : s .state ,
429+ Cost : s .cost ,
430+ HtlcTxHash : s .htlcTxHash ,
424431 },
425432 )
426433 if err != nil {
@@ -563,11 +570,21 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
563570 s .InitiationHeight ,
564571 )
565572
573+ // If we've revealed the preimage in a previous run, we expect to have
574+ // recorded the htlc tx hash. We use this to re-register for
575+ // confirmation, to be sure that we'll keep tracking the same htlc. For
576+ // older swaps, this field may not be populated even though the preimage
577+ // has already been revealed.
578+ if s .state == loopdb .StatePreimageRevealed && s .htlcTxHash == nil {
579+ s .log .Warnf ("No htlc tx hash available, registering with " +
580+ "just the pkscript" )
581+ }
582+
566583 ctx , cancel := context .WithCancel (globalCtx )
567584 defer cancel ()
568585 htlcConfChan , htlcErrChan , err :=
569586 s .lnd .ChainNotifier .RegisterConfirmationsNtfn (
570- ctx , nil , s .htlc .PkScript , 1 ,
587+ ctx , s . htlcTxHash , s .htlc .PkScript , 1 ,
571588 s .InitiationHeight ,
572589 )
573590 if err != nil {
@@ -680,8 +697,10 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
680697 }
681698 }
682699
683- s .log .Infof ("Htlc tx %v at height %v" , txConf .Tx .TxHash (),
684- txConf .BlockHeight )
700+ htlcTxHash := txConf .Tx .TxHash ()
701+ s .log .Infof ("Htlc tx %v at height %v" , htlcTxHash , txConf .BlockHeight )
702+
703+ s .htlcTxHash = & htlcTxHash
685704
686705 return txConf , nil
687706}
@@ -694,13 +713,14 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
694713// sweep offchain. So we must make sure we sweep successfully before on-chain
695714// timeout.
696715func (s * loopOutSwap ) waitForHtlcSpendConfirmed (globalCtx context.Context ,
697- spendFunc func () error ) (* chainntnfs.SpendDetail , error ) {
716+ htlc wire.OutPoint , spendFunc func () error ) (* chainntnfs.SpendDetail ,
717+ error ) {
698718
699719 // Register the htlc spend notification.
700720 ctx , cancel := context .WithCancel (globalCtx )
701721 defer cancel ()
702722 spendChan , spendErr , err := s .lnd .ChainNotifier .RegisterSpendNtfn (
703- ctx , nil , s .htlc .PkScript , s .InitiationHeight ,
723+ ctx , & htlc , s .htlc .PkScript , s .InitiationHeight ,
704724 )
705725 if err != nil {
706726 return nil , fmt .Errorf ("register spend ntfn: %v" , err )
0 commit comments