@@ -414,23 +414,16 @@ func TestCustomSweepConfTarget(t *testing.T) {
414414// not detected our settle) and settle the off chain htlc, indicating that the
415415// server successfully settled using the preimage push. In this test, we need
416416// to start with a fee rate that will be too high, then progress to an
417- // acceptable one. We do this by starting with a high confirmation target with
418- // a high fee, and setting the default confirmation fee (which our swap will
419- // drop down to if it is not confirming in time) to a lower fee. This is not
420- // intuitive (lower confs having lower fees), but it allows up to mock fee
421- // changes.
417+ // acceptable one.
422418func TestPreimagePush (t * testing.T ) {
423419 defer test .Guard (t )()
424420
425421 lnd := test .NewMockLnd ()
426422 ctx := test .NewContext (t , lnd )
427423 server := newServerMock (lnd )
428424
429- // Start with a high confirmation delta which will have a very high fee
430- // attached to it.
431425 testReq := * testRequest
432- testReq .SweepConfTarget = testLoopOutMinOnChainCltvDelta -
433- DefaultSweepConfTargetDelta - 1
426+ testReq .SweepConfTarget = 10
434427 testReq .Expiry = ctx .Lnd .Height + testLoopOutMinOnChainCltvDelta
435428
436429 // We set our mock fee estimate for our target sweep confs to be our
@@ -442,11 +435,6 @@ func TestPreimagePush(t *testing.T) {
442435 ),
443436 )
444437
445- // We set the fee estimate for our default confirmation target very
446- // low, so that once we drop down to our default confs we will start
447- // trying to sweep the preimage.
448- ctx .Lnd .SetFeeEstimate (DefaultSweepConfTarget , 1 )
449-
450438 cfg := newSwapConfig (
451439 & lnd .LndServices , newStoreMock (t ), server ,
452440 )
@@ -520,15 +508,15 @@ func TestPreimagePush(t *testing.T) {
520508 // preimage is not revealed, we also do not expect a preimage push.
521509 expiryChan <- testTime
522510
523- // Now, we notify the height at which the client will start using the
524- // default confirmation target. This has the effect of lowering our fees
525- // so that the client still start sweeping.
526- defaultConfTargetHeight := ctx .Lnd .Height + testLoopOutMinOnChainCltvDelta -
527- DefaultSweepConfTargetDelta
528- blockEpochChan <- defaultConfTargetHeight
511+ // Now we decrease our fees for the swap's confirmation target to less
512+ // than the maximum miner fee.
513+ ctx .Lnd .SetFeeEstimate (testReq .SweepConfTarget , chainfee .SatPerKWeight (
514+ testReq .MaxMinerFee / 2 ,
515+ ))
529516
530- // This time when we tick the expiry chan, our fees are lower than the
531- // swap max, so we expect it to prompt a sweep.
517+ // Now when we report a new block and tick our expiry fee timer, and
518+ // fees are acceptably low so we expect our sweep to be published.
519+ blockEpochChan <- ctx .Lnd .Height + 2
532520 expiryChan <- testTime
533521
534522 // Expect a signing request for the HTLC success transaction.
@@ -593,3 +581,119 @@ func TestPreimagePush(t *testing.T) {
593581
594582 require .NoError (t , <- errChan )
595583}
584+
585+ // TestExpiryBeforeReveal tests the case where the on-chain HTLC expires before
586+ // we have revealed our preimage, demonstrating that we do not reveal our
587+ // preimage once we've reached our expiry height.
588+ func TestExpiryBeforeReveal (t * testing.T ) {
589+ defer test .Guard (t )()
590+
591+ lnd := test .NewMockLnd ()
592+ ctx := test .NewContext (t , lnd )
593+ server := newServerMock (lnd )
594+
595+ testReq := * testRequest
596+
597+ // Set on-chain HTLC CLTV.
598+ testReq .Expiry = ctx .Lnd .Height + testLoopOutMinOnChainCltvDelta
599+
600+ // Set our fee estimate to higher than our max miner fee will allow.
601+ lnd .SetFeeEstimate (testReq .SweepConfTarget , chainfee .SatPerKWeight (
602+ testReq .MaxMinerFee * 2 ,
603+ ))
604+
605+ // Setup the cfg using mock server and init a loop out request.
606+ cfg := newSwapConfig (
607+ & lnd .LndServices , newStoreMock (t ), server ,
608+ )
609+ initResult , err := newLoopOutSwap (
610+ context .Background (), cfg , ctx .Lnd .Height , & testReq ,
611+ )
612+ require .NoError (t , err )
613+ swap := initResult .swap
614+
615+ // Set up the required dependencies to execute the swap.
616+ sweeper := & sweep.Sweeper {Lnd : & lnd .LndServices }
617+ blockEpochChan := make (chan interface {})
618+ statusChan := make (chan SwapInfo )
619+ expiryChan := make (chan time.Time )
620+ timerFactory := func (_ time.Duration ) <- chan time.Time {
621+ return expiryChan
622+ }
623+
624+ errChan := make (chan error )
625+ go func () {
626+ err := swap .execute (context .Background (), & executeConfig {
627+ statusChan : statusChan ,
628+ blockEpochChan : blockEpochChan ,
629+ timerFactory : timerFactory ,
630+ sweeper : sweeper ,
631+ }, ctx .Lnd .Height )
632+ if err != nil {
633+ log .Error (err )
634+ }
635+ errChan <- err
636+ }()
637+
638+ // The swap should be found in its initial state.
639+ cfg .store .(* storeMock ).assertLoopOutStored ()
640+ state := <- statusChan
641+ require .Equal (t , loopdb .StateInitiated , state .State )
642+
643+ // We'll then pay both the swap and prepay invoice, which should trigger
644+ // the server to publish the on-chain HTLC.
645+ signalSwapPaymentResult := ctx .AssertPaid (swapInvoiceDesc )
646+ signalPrepaymentResult := ctx .AssertPaid (prepayInvoiceDesc )
647+
648+ signalSwapPaymentResult (nil )
649+ signalPrepaymentResult (nil )
650+
651+ // Notify the confirmation notification for the HTLC.
652+ ctx .AssertRegisterConf (false , defaultConfirmations )
653+
654+ // Advance the block height to get the HTLC confirmed.
655+ height := ctx .Lnd .Height + 1
656+ blockEpochChan <- height
657+
658+ htlcTx := wire .NewMsgTx (2 )
659+ htlcTx .AddTxOut (& wire.TxOut {
660+ Value : int64 (swap .AmountRequested ),
661+ PkScript : swap .htlc .PkScript ,
662+ })
663+ ctx .NotifyConf (htlcTx )
664+
665+ // The client should then register for a spend of the HTLC and attempt
666+ // to sweep it using the custom confirmation target.
667+ ctx .AssertRegisterSpendNtfn (swap .htlc .PkScript )
668+
669+ // Assert that we made a query to track our payment, as required for
670+ // preimage push tracking.
671+ ctx .AssertTrackPayment ()
672+
673+ // Tick the expiry channel. Because our max miner fee is too high, we
674+ // won't attempt a sweep at this point.
675+ expiryChan <- testTime
676+
677+ // Now we decrease our conf target to less than our max miner fee.
678+ lnd .SetFeeEstimate (testReq .SweepConfTarget , chainfee .SatPerKWeight (
679+ testReq .MaxMinerFee / 2 ,
680+ ))
681+
682+ // Advance the block height to the point where we would do timeout
683+ // instead of pushing the preimage.
684+ blockEpochChan <- testReq .Expiry + height
685+
686+ // Tick our expiry channel again to trigger another sweep attempt.
687+ expiryChan <- testTime
688+
689+ // We should see our swap marked as failed.
690+ cfg .store .(* storeMock ).assertLoopOutState (
691+ loopdb .StateFailTimeout ,
692+ )
693+ status := <- statusChan
694+ require .Equal (
695+ t , status .State , loopdb .StateFailTimeout ,
696+ )
697+
698+ require .Nil (t , <- errChan )
699+ }
0 commit comments