@@ -414,23 +414,16 @@ func TestCustomSweepConfTarget(t *testing.T) {
414
414
// not detected our settle) and settle the off chain htlc, indicating that the
415
415
// server successfully settled using the preimage push. In this test, we need
416
416
// 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.
422
418
func TestPreimagePush (t * testing.T ) {
423
419
defer test .Guard (t )()
424
420
425
421
lnd := test .NewMockLnd ()
426
422
ctx := test .NewContext (t , lnd )
427
423
server := newServerMock (lnd )
428
424
429
- // Start with a high confirmation delta which will have a very high fee
430
- // attached to it.
431
425
testReq := * testRequest
432
- testReq .SweepConfTarget = testLoopOutMinOnChainCltvDelta -
433
- DefaultSweepConfTargetDelta - 1
426
+ testReq .SweepConfTarget = 10
434
427
testReq .Expiry = ctx .Lnd .Height + testLoopOutMinOnChainCltvDelta
435
428
436
429
// We set our mock fee estimate for our target sweep confs to be our
@@ -442,11 +435,6 @@ func TestPreimagePush(t *testing.T) {
442
435
),
443
436
)
444
437
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
-
450
438
cfg := newSwapConfig (
451
439
& lnd .LndServices , newStoreMock (t ), server ,
452
440
)
@@ -520,15 +508,15 @@ func TestPreimagePush(t *testing.T) {
520
508
// preimage is not revealed, we also do not expect a preimage push.
521
509
expiryChan <- testTime
522
510
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
+ ))
529
516
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
532
520
expiryChan <- testTime
533
521
534
522
// Expect a signing request for the HTLC success transaction.
@@ -593,3 +581,119 @@ func TestPreimagePush(t *testing.T) {
593
581
594
582
require .NoError (t , <- errChan )
595
583
}
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