@@ -2773,9 +2773,20 @@ func testCustomChannelsFee(_ context.Context,
27732773// testCustomChannelsHtlcForceClose tests that we can force close a channel 
27742774// with HTLCs in both directions and that the HTLC outputs are correctly 
27752775// swept. 
2776- func  testCustomChannelsHtlcForceClose (_  context.Context , net  * NetworkHarness ,
2776+ func  testCustomChannelsHtlcForceClose (ctxb  context.Context , net  * NetworkHarness ,
27772777	t  * harnessTest ) {
27782778
2779+ 	runCustomChannelsHtlcForceClose (ctxb , t , net , false )
2780+ 	runCustomChannelsHtlcForceClose (ctxb , t , net , true )
2781+ }
2782+ 
2783+ // runCustomChannelsHtlcForceClose is a helper function that runs the HTLC force 
2784+ // close test with the given MPP setting. 
2785+ func  runCustomChannelsHtlcForceClose (ctxb  context.Context , t  * harnessTest ,
2786+ 	net  * NetworkHarness , mpp  bool ) {
2787+ 
2788+ 	t .Logf ("Running test with MPP: %v" , mpp )
2789+ 
27792790	lndArgs  :=  slices .Clone (lndArgsTemplate )
27802791	litdArgs  :=  slices .Clone (litdArgsTemplate )
27812792
@@ -2829,7 +2840,6 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28292840	// With the assets created, and synced -- we'll now open the channel 
28302841	// between Alice and Bob. 
28312842	t .Logf ("Opening asset channels..." )
2832- 	ctxb  :=  context .Background ()
28332843	assetFundResp , err  :=  aliceTap .FundChannel (
28342844		ctxb , & tchrpc.FundChannelRequest {
28352845			AssetAmount :        fundingAmount ,
@@ -2853,7 +2863,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28532863	// to be able to extend HTLCs in the other direction. 
28542864	const  (
28552865		numPayments    =  10 
2856- 		keySendAmount  =  1_000 
2866+ 		keySendAmount  =  2_500 
28572867	)
28582868	for  i  :=  0 ; i  <  numPayments ; i ++  {
28592869		sendAssetKeySendPayment (
@@ -2866,11 +2876,19 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28662876	// Now that both parties have some funds, we'll move onto the main test. 
28672877	// 
28682878	// We'll make 2 hodl invoice for each peer, so 4 total. From Alice's 
2869- 	// PoV, she'll have two outgoing HTLCs, and two incoming HTLCs. 
2879+ 	// PoV, she'll have two outgoing HTLCs (or +4 with MPP), and two 
2880+ 	// incoming HTLCs. 
28702881	var  (
28712882		bobHodlInvoices    []assetHodlInvoice 
28722883		aliceHodlInvoices  []assetHodlInvoice 
2873- 		assetInvoiceAmt    =  100 
2884+ 
2885+ 		// The default oracle rate is 17_180 mSat/asset unit, so 10_000 
2886+ 		// will be equal to 171_800_000 mSat. When we use the mpp bool 
2887+ 		// for the smallShards param of payInvoiceWithAssets, that 
2888+ 		// means we'll split the payment into shards of 80_000_000 mSat 
2889+ 		// max. So we'll get three shards per payment. 
2890+ 		assetInvoiceAmt    =  10_000 
2891+ 		assetsPerMPPShard  =  4656 
28742892	)
28752893	for  i  :=  0 ; i  <  2 ; i ++  {
28762894		bobHodlInvoices  =  append (
@@ -2892,7 +2910,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28922910	// yet. 
28932911	for  _ , aliceInvoice  :=  range  aliceHodlInvoices  {
28942912		payInvoiceWithAssets (
2895- 			t .t , bob , alice , aliceInvoice .payReq , assetID , false ,
2913+ 			t .t , bob , alice , aliceInvoice .payReq , assetID , mpp ,
28962914			fn .Some (lnrpc .Payment_IN_FLIGHT ),
28972915		)
28982916	}
@@ -2903,9 +2921,15 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29032921		)
29042922	}
29052923
2906- 	// At this point, both sides should have 4 HTLCs active. 
2907- 	assertNumHtlcs (t .t , alice , 4 )
2908- 	assertNumHtlcs (t .t , bob , 4 )
2924+ 	// At this point, both sides should have 4 (or +4 with MPP) HTLCs 
2925+ 	// active. 
2926+ 	numHtlcs  :=  4 
2927+ 	if  mpp  {
2928+ 		numAdditionalShards  :=  assetInvoiceAmt  /  assetsPerMPPShard 
2929+ 		numHtlcs  +=  numAdditionalShards  *  2 
2930+ 	}
2931+ 	assertNumHtlcs (t .t , alice , numHtlcs )
2932+ 	assertNumHtlcs (t .t , bob , numHtlcs )
29092933
29102934	// Before we force close, we'll grab the current height, the CSV delay 
29112935	// needed, and also the absolute timeout of the set of active HTLCs. 
@@ -2947,8 +2971,8 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29472971	// At this point, the commitment transaction has been mined, and we have 
29482972	// 4 total HTLCs on Alice's commitment transaction: 
29492973	// 
2950- 	//  * 2x outgoing HTLCs to  Alice to Bob 
2951- 	//  * 2x incoming HTLCs from Bob to Alice 
2974+ 	//  * 2x outgoing HTLCs from  Alice to Bob 
2975+ 	//  * 2x incoming HTLCs from Bob to Alice (+2 with MPP)  
29522976	// 
29532977	// We'll leave half the HTLCs timeout, while pulling the other half. 
29542978	// To start, we'll signal Bob to settle one of his incoming HTLCs on 
@@ -2971,7 +2995,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29712995	// We'll mine an empty block to get the sweeper to tick. 
29722996	mineBlocks (t , net , 1 , 0 )
29732997
2974- 	sweepTx1 , err  :=  waitForNTxsInMempool (
2998+ 	bobSweepTx1 , err  :=  waitForNTxsInMempool (
29752999		net .Miner .Client , 1 , shortTimeout ,
29763000	)
29773001	require .NoError (t .t , err )
@@ -2984,15 +3008,17 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29843008	// At this point, we should have the next sweep transaction in the 
29853009	// mempool: Bob's incoming HTLC sweep directly off the commitment 
29863010	// transaction. 
2987- 	sweepTx2 , err  :=  waitForNTxsInMempool (net .Miner .Client , 1 , shortTimeout )
3011+ 	bobSweepTx2 , err  :=  waitForNTxsInMempool (
3012+ 		net .Miner .Client , 1 , shortTimeout ,
3013+ 	)
29883014	require .NoError (t .t , err )
29893015
29903016	// We'll now mine the next block, which should confirm Bob's HTLC sweep 
29913017	// transaction. 
29923018	mineBlocks (t , net , 1 , 1 )
29933019
2994- 	bobSweepTransfer1  :=  locateAssetTransfers (t .t , bobTap , * sweepTx1 [0 ])
2995- 	bobSweepTransfer2  :=  locateAssetTransfers (t .t , bobTap , * sweepTx2 [0 ])
3020+ 	bobSweepTransfer1  :=  locateAssetTransfers (t .t , bobTap , * bobSweepTx1 [0 ])
3021+ 	bobSweepTransfer2  :=  locateAssetTransfers (t .t , bobTap , * bobSweepTx2 [0 ])
29963022	t .Logf ("Bob's sweep transfer 1: %v" ,
29973023		toProtoJSON (t .t , bobSweepTransfer1 ))
29983024	t .Logf ("Bob's sweep transfer 2: %v" ,
@@ -3006,9 +3032,8 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30063032	// RFQ conversion. 
30073033	bobExpectedBalance  :=  closeExpiryInfo .remoteAssetBalance  + 
30083034		uint64 (assetInvoiceAmt - 1 )
3009- 	assertSpendableBalance (
3010- 		t .t , bobTap , assetID , bobExpectedBalance ,
3011- 	)
3035+ 	t .Logf ("Expecting Bob's balance to be %d" , bobExpectedBalance )
3036+ 	assertSpendableBalance (t .t , bobTap , assetID , bobExpectedBalance )
30123037
30133038	// With Bob's HTLC settled, we'll now have Alice do the same. For her, 
30143039	// it'll be a 2nd level sweep, which requires an extra transaction. 
@@ -3018,15 +3043,26 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30183043	// that she's swept everything properly. With the way the sweeper works, 
30193044	// we need to mine one extra block before the sweeper picks things up. 
30203045	mineBlocks (t , net , 1 , 0 )
3021- 	time .Sleep (time .Second  *  1 )
3046+ 
3047+ 	aliceSweepTx1 , err  :=  waitForNTxsInMempool (
3048+ 		net .Miner .Client , 1 , shortTimeout ,
3049+ 	)
3050+ 	require .NoError (t .t , err )
3051+ 
30223052	mineBlocks (t , net , 1 , 1 )
30233053
3054+ 	aliceSweepTransfer1  :=  locateAssetTransfers (
3055+ 		t .t , aliceTap , * aliceSweepTx1 [0 ],
3056+ 	)
3057+ 	t .Logf ("Alice's sweep transfer 1: %v" ,
3058+ 		toProtoJSON (t .t , aliceSweepTransfer1 ))
3059+ 
30243060	t .Logf ("Confirming Alice's to-local sweep" )
30253061
30263062	// With this extra block mined, Alice's settled balance should be the 
30273063	// starting balance, minus the 2 HTLCs, plus her settled balance. 
30283064	aliceExpectedBalance  :=  itestAsset .Amount  -  fundingAmount 
3029- 	aliceExpectedBalance  +=  uint64 ( closeExpiryInfo .localAssetBalance ) 
3065+ 	aliceExpectedBalance  +=  closeExpiryInfo .localAssetBalance 
30303066	assertSpendableBalance (
30313067		t .t , aliceTap , assetID , aliceExpectedBalance ,
30323068	)
@@ -3056,9 +3092,27 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30563092	// If the block mined above didn't also mine our sweep, then we'll mine 
30573093	// one final block which will confirm Alice's sweep transaction. 
30583094	if  len (sweepBlocks [0 ].Transactions ) ==  1  {
3095+ 		sweepTx , err  :=  waitForNTxsInMempool (
3096+ 			net .Miner .Client , 1 , shortTimeout ,
3097+ 		)
3098+ 		require .NoError (t .t , err )
3099+ 
30593100		// With the sweep transaction in the mempool, we'll mine a block 
30603101		// to confirm the sweep. 
30613102		mineBlocks (t , net , 1 , 1 )
3103+ 
3104+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3105+ 			t .t , aliceTap , * sweepTx [0 ],
3106+ 		)
3107+ 		t .Logf ("Alice's first-level sweep transfer: %v" ,
3108+ 			toProtoJSON (t .t , aliceSweepTransfer ))
3109+ 	} else  {
3110+ 		sweepTx  :=  sweepBlocks [0 ].Transactions [1 ]
3111+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3112+ 			t .t , aliceTap , sweepTx .TxHash (),
3113+ 		)
3114+ 		t .Logf ("Alice's first-level sweep transfer: %v" ,
3115+ 			toProtoJSON (t .t , aliceSweepTransfer ))
30623116	}
30633117
30643118	t .Logf ("Confirming Alice's second level remote HTLC success sweep" )
@@ -3085,7 +3139,25 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30853139	// If the block mined above didn't also mine our sweep, then we'll mine 
30863140	// one final block which will confirm Alice's sweep transaction. 
30873141	if  len (sweepBlocks [0 ].Transactions ) ==  1  {
3142+ 		sweepTx , err  :=  waitForNTxsInMempool (
3143+ 			net .Miner .Client , 1 , shortTimeout ,
3144+ 		)
3145+ 		require .NoError (t .t , err )
3146+ 
30883147		mineBlocks (t , net , 1 , 1 )
3148+ 
3149+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3150+ 			t .t , aliceTap , * sweepTx [0 ],
3151+ 		)
3152+ 		t .Logf ("Alice's second-level sweep transfer: %v" ,
3153+ 			toProtoJSON (t .t , aliceSweepTransfer ))
3154+ 	} else  {
3155+ 		sweepTx  :=  sweepBlocks [0 ].Transactions [1 ]
3156+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3157+ 			t .t , aliceTap , sweepTx .TxHash (),
3158+ 		)
3159+ 		t .Logf ("Alice's second-level sweep transfer: %v" ,
3160+ 			toProtoJSON (t .t , aliceSweepTransfer ))
30893161	}
30903162
30913163	// With the sweep transaction confirmed, Alice's balance should have 
@@ -3153,14 +3225,33 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
31533225	// If the block mined above didn't also mine our sweep, then we'll mine 
31543226	// one final block which will confirm Alice's sweep transaction. 
31553227	if  len (sweepBlocks [0 ].Transactions ) ==  1  {
3228+ 		sweepTx , err  :=  waitForNTxsInMempool (
3229+ 			net .Miner .Client , 1 , shortTimeout ,
3230+ 		)
3231+ 		require .NoError (t .t , err )
3232+ 
31563233		// We'll mine one final block which will confirm Alice's sweep 
31573234		// transaction. 
31583235		mineBlocks (t , net , 1 , 1 )
3236+ 
3237+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3238+ 			t .t , aliceTap , * sweepTx [0 ],
3239+ 		)
3240+ 		t .Logf ("Alice's final timeout sweep transfer: %v" ,
3241+ 			toProtoJSON (t .t , aliceSweepTransfer ))
3242+ 	} else  {
3243+ 		sweepTx  :=  sweepBlocks [0 ].Transactions [1 ]
3244+ 		aliceSweepTransfer  :=  locateAssetTransfers (
3245+ 			t .t , aliceTap , sweepTx .TxHash (),
3246+ 		)
3247+ 		t .Logf ("Alice's final timeout sweep transfer: %v" ,
3248+ 			toProtoJSON (t .t , aliceSweepTransfer ))
31593249	}
31603250
31613251	// Finally, we'll assert that Alice's balance has been incremented by 
31623252	// the timeout value. 
31633253	aliceExpectedBalance  +=  uint64 (assetInvoiceAmt  -  1 )
3254+ 	t .Logf ("Expecting Alice's balance to be %d" , aliceExpectedBalance )
31643255	assertSpendableBalance (
31653256		t .t , aliceTap , assetID , aliceExpectedBalance ,
31663257	)
0 commit comments