@@ -28,6 +28,8 @@ import (
28
28
"github.com/lightningnetwork/lnd/fn"
29
29
"github.com/lightningnetwork/lnd/lnrpc"
30
30
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
31
+ "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
32
+ "github.com/lightningnetwork/lnd/lnrpc/walletrpc"
31
33
"github.com/lightningnetwork/lnd/lntest"
32
34
"github.com/lightningnetwork/lnd/lntest/node"
33
35
"github.com/lightningnetwork/lnd/lntest/port"
@@ -2220,12 +2222,12 @@ func testCustomChannelsBreach(ctx context.Context, net *NetworkHarness,
2220
2222
t .Logf ("Charlie UTXOs after breach: %v" , toProtoJSON (t .t , charlieUTXOs ))
2221
2223
}
2222
2224
2223
- // testCustomChannelsLiquidtyEdgeCasesCore is the core logic of the liquidity
2225
+ // testCustomChannelsLiquidityEdgeCasesCore is the core logic of the liquidity
2224
2226
// edge cases. This test goes through certain scenarios that expose edge cases
2225
2227
// and behaviors that proved to be buggy in the past and have been directly
2226
2228
// addressed. It accepts an extra parameter which dictates whether it should use
2227
2229
// group keys or asset IDs.
2228
- func testCustomChannelsLiquidtyEdgeCasesCore (ctx context.Context ,
2230
+ func testCustomChannelsLiquidityEdgeCasesCore (ctx context.Context ,
2229
2231
net * NetworkHarness , t * harnessTest , groupMode bool ) {
2230
2232
2231
2233
lndArgs := slices .Clone (lndArgsTemplate )
@@ -2723,6 +2725,69 @@ func testCustomChannelsLiquidtyEdgeCasesCore(ctx context.Context,
2723
2725
)
2724
2726
2725
2727
logBalance (t .t , nodes , assetID , "after small manual rfq" )
2728
+
2729
+ // Edge case: Fabia creates an invoice which Erin cannot satisfy with
2730
+ // his side of asset liquidity. This tests that Erin will not try to
2731
+ // add an HTLC with more asset units than what his local balance is. To
2732
+ // validate that the channel is still healthy, we follow up with a
2733
+ // smaller invoice payment which is meant to succeed.
2734
+
2735
+ // We now create a hodl invoice on Fabia, for 125k assets.
2736
+ hodlInv = createAssetHodlInvoice (t .t , erin , fabia , 125_000 , assetID )
2737
+
2738
+ htlcStream , err := erin .RouterClient .SubscribeHtlcEvents (
2739
+ ctx , & routerrpc.SubscribeHtlcEventsRequest {},
2740
+ )
2741
+ require .NoError (t .t , err )
2742
+
2743
+ // Charlie tries to pay, this is not meant to succeed, as Erin does not
2744
+ // have enough assets to forward to Fabia.
2745
+ payInvoiceWithAssets (
2746
+ t .t , charlie , dave , hodlInv .payReq , assetID ,
2747
+ withFailure (lnrpc .Payment_IN_FLIGHT , failureNone ),
2748
+ )
2749
+
2750
+ // Let's check that at least 2 HTLCs were added on the Erin->Fabia link,
2751
+ // which means that Erin would have an extra incoming HTLC for each
2752
+ // outgoing one. So we expect a minimum of 4 HTLCs present on Erin.
2753
+ assertMinNumHtlcs (t .t , erin , 4 )
2754
+
2755
+ // We also want to make sure that at least one failure occurred that
2756
+ // hinted at the problem (not enough assets to forward).
2757
+ assertHtlcEvents (
2758
+ t .t , htlcStream , withNumEvents (1 ),
2759
+ withLinkFailure (routerrpc .FailureDetail_INSUFFICIENT_BALANCE ),
2760
+ )
2761
+
2762
+ logBalance (t .t , nodes , assetID , "with min 4 present HTLCs" )
2763
+
2764
+ // Now Fabia cancels the invoice, this is meant to cancel back any
2765
+ // locked in HTLCs and reset Erin's local balance back to its original
2766
+ // value.
2767
+ payHash = hodlInv .preimage .Hash ()
2768
+ _ , err = fabia .InvoicesClient .CancelInvoice (
2769
+ ctx , & invoicesrpc.CancelInvoiceMsg {
2770
+ PaymentHash : payHash [:],
2771
+ },
2772
+ )
2773
+ require .NoError (t .t , err )
2774
+
2775
+ // Let's assert that Erin cancelled all his HTLCs.
2776
+ assertNumHtlcs (t .t , erin , 0 )
2777
+
2778
+ logBalance (t .t , nodes , assetID , "after hodl cancel & 0 present HTLCs" )
2779
+
2780
+ // Now let's create a smaller invoice and pay it, to validate that the
2781
+ // channel is still healthy.
2782
+ invoiceResp = createAssetInvoice (
2783
+ t .t , erin , fabia , 50_000 , assetID ,
2784
+ )
2785
+
2786
+ payInvoiceWithAssets (
2787
+ t .t , charlie , dave , invoiceResp .PaymentRequest , assetID ,
2788
+ )
2789
+
2790
+ logBalance (t .t , nodes , assetID , "after safe asset htlc failure" )
2726
2791
}
2727
2792
2728
2793
// testCustomChannelsLiquidityEdgeCases is a test that runs through some
@@ -2732,7 +2797,7 @@ func testCustomChannelsLiquidityEdgeCases(ctx context.Context,
2732
2797
2733
2798
// Run liquidity edge cases and only use single asset IDs for invoices
2734
2799
// and payments.
2735
- testCustomChannelsLiquidtyEdgeCasesCore (ctx , net , t , false )
2800
+ testCustomChannelsLiquidityEdgeCasesCore (ctx , net , t , false )
2736
2801
}
2737
2802
2738
2803
// testCustomChannelsLiquidityEdgeCasesGroup is a test that runs through some
@@ -2742,7 +2807,7 @@ func testCustomChannelsLiquidityEdgeCasesGroup(ctx context.Context,
2742
2807
2743
2808
// Run liquidity edge cases and only use group keys for invoices and
2744
2809
// payments.
2745
- testCustomChannelsLiquidtyEdgeCasesCore (ctx , net , t , true )
2810
+ testCustomChannelsLiquidityEdgeCasesCore (ctx , net , t , true )
2746
2811
}
2747
2812
2748
2813
// testCustomChannelsStrictForwarding is a test that tests the strict forwarding
0 commit comments