@@ -30,6 +30,7 @@ import (
30
30
"github.com/lightningnetwork/lnd/fn"
31
31
"github.com/lightningnetwork/lnd/lnrpc"
32
32
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
33
+ "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
33
34
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
34
35
"github.com/lightningnetwork/lnd/lntest"
35
36
"github.com/lightningnetwork/lnd/lntest/node"
@@ -2601,12 +2602,12 @@ func testCustomChannelsBreach(ctx context.Context, net *NetworkHarness,
2601
2602
t .Logf ("Charlie UTXOs after breach: %v" , toProtoJSON (t .t , charlieUTXOs ))
2602
2603
}
2603
2604
2604
- // testCustomChannelsLiquidtyEdgeCasesCore is the core logic of the liquidity
2605
+ // testCustomChannelsLiquidityEdgeCasesCore is the core logic of the liquidity
2605
2606
// edge cases. This test goes through certain scenarios that expose edge cases
2606
2607
// and behaviors that proved to be buggy in the past and have been directly
2607
2608
// addressed. It accepts an extra parameter which dictates whether it should use
2608
2609
// group keys or asset IDs.
2609
- func testCustomChannelsLiquidtyEdgeCasesCore (ctx context.Context ,
2610
+ func testCustomChannelsLiquidityEdgeCasesCore (ctx context.Context ,
2610
2611
net * NetworkHarness , t * harnessTest , groupMode bool ) {
2611
2612
2612
2613
lndArgs := slices .Clone (lndArgsTemplate )
@@ -3104,6 +3105,69 @@ func testCustomChannelsLiquidtyEdgeCasesCore(ctx context.Context,
3104
3105
)
3105
3106
3106
3107
logBalance (t .t , nodes , assetID , "after small manual rfq" )
3108
+
3109
+ // Edge case: Fabia creates an invoice which Erin cannot satisfy with
3110
+ // his side of asset liquidity. This tests that Erin will not try to
3111
+ // add an HTLC with more asset units than what his local balance is. To
3112
+ // validate that the channel is still healthy, we follow up with a
3113
+ // smaller invoice payment which is meant to succeed.
3114
+
3115
+ // We now create a hodl invoice on Fabia, for 125k assets.
3116
+ hodlInv = createAssetHodlInvoice (t .t , erin , fabia , 125_000 , assetID )
3117
+
3118
+ htlcStream , err := erin .RouterClient .SubscribeHtlcEvents (
3119
+ ctx , & routerrpc.SubscribeHtlcEventsRequest {},
3120
+ )
3121
+ require .NoError (t .t , err )
3122
+
3123
+ // Charlie tries to pay, this is not meant to succeed, as Erin does not
3124
+ // have enough assets to forward to Fabia.
3125
+ payInvoiceWithAssets (
3126
+ t .t , charlie , dave , hodlInv .payReq , assetID ,
3127
+ withFailure (lnrpc .Payment_IN_FLIGHT , failureNone ),
3128
+ )
3129
+
3130
+ // Let's check that at least 2 HTLCs were added on the Erin->Fabia link,
3131
+ // which means that Erin would have an extra incoming HTLC for each
3132
+ // outgoing one. So we expect a minimum of 4 HTLCs present on Erin.
3133
+ assertMinNumHtlcs (t .t , erin , 4 )
3134
+
3135
+ // We also want to make sure that at least one failure occurred that
3136
+ // hinted at the problem (not enough assets to forward).
3137
+ assertHtlcEvents (
3138
+ t .t , htlcStream , withNumEvents (1 ),
3139
+ withLinkFailure (routerrpc .FailureDetail_INSUFFICIENT_BALANCE ),
3140
+ )
3141
+
3142
+ logBalance (t .t , nodes , assetID , "with min 4 present HTLCs" )
3143
+
3144
+ // Now Fabia cancels the invoice, this is meant to cancel back any
3145
+ // locked in HTLCs and reset Erin's local balance back to its original
3146
+ // value.
3147
+ payHash = hodlInv .preimage .Hash ()
3148
+ _ , err = fabia .InvoicesClient .CancelInvoice (
3149
+ ctx , & invoicesrpc.CancelInvoiceMsg {
3150
+ PaymentHash : payHash [:],
3151
+ },
3152
+ )
3153
+ require .NoError (t .t , err )
3154
+
3155
+ // Let's assert that Erin cancelled all his HTLCs.
3156
+ assertNumHtlcs (t .t , erin , 0 )
3157
+
3158
+ logBalance (t .t , nodes , assetID , "after hodl cancel & 0 present HTLCs" )
3159
+
3160
+ // Now let's create a smaller invoice and pay it, to validate that the
3161
+ // channel is still healthy.
3162
+ invoiceResp = createAssetInvoice (
3163
+ t .t , erin , fabia , 50_000 , assetID ,
3164
+ )
3165
+
3166
+ payInvoiceWithAssets (
3167
+ t .t , charlie , dave , invoiceResp .PaymentRequest , assetID ,
3168
+ )
3169
+
3170
+ logBalance (t .t , nodes , assetID , "after safe asset htlc failure" )
3107
3171
}
3108
3172
3109
3173
// testCustomChannelsLiquidityEdgeCases is a test that runs through some
@@ -3113,7 +3177,7 @@ func testCustomChannelsLiquidityEdgeCases(ctx context.Context,
3113
3177
3114
3178
// Run liquidity edge cases and only use single asset IDs for invoices
3115
3179
// and payments.
3116
- testCustomChannelsLiquidtyEdgeCasesCore (ctx , net , t , false )
3180
+ testCustomChannelsLiquidityEdgeCasesCore (ctx , net , t , false )
3117
3181
}
3118
3182
3119
3183
// testCustomChannelsLiquidityEdgeCasesGroup is a test that runs through some
@@ -3123,7 +3187,7 @@ func testCustomChannelsLiquidityEdgeCasesGroup(ctx context.Context,
3123
3187
3124
3188
// Run liquidity edge cases and only use group keys for invoices and
3125
3189
// payments.
3126
- testCustomChannelsLiquidtyEdgeCasesCore (ctx , net , t , true )
3190
+ testCustomChannelsLiquidityEdgeCasesCore (ctx , net , t , true )
3127
3191
}
3128
3192
3129
3193
// testCustomChannelsStrictForwarding is a test that tests the strict forwarding
0 commit comments