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