@@ -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 (
@@ -2870,7 +2880,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28702880 var (
28712881 bobHodlInvoices []assetHodlInvoice
28722882 aliceHodlInvoices []assetHodlInvoice
2873- assetInvoiceAmt = 100
2883+ assetInvoiceAmt = 5_000
28742884 )
28752885 for i := 0 ; i < 2 ; i ++ {
28762886 bobHodlInvoices = append (
@@ -2892,7 +2902,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
28922902 // yet.
28932903 for _ , aliceInvoice := range aliceHodlInvoices {
28942904 payInvoiceWithAssets (
2895- t .t , bob , alice , aliceInvoice .payReq , assetID , false ,
2905+ t .t , bob , alice , aliceInvoice .payReq , assetID , mpp ,
28962906 fn .Some (lnrpc .Payment_IN_FLIGHT ),
28972907 )
28982908 }
@@ -2903,9 +2913,14 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29032913 )
29042914 }
29052915
2906- // At this point, both sides should have 4 HTLCs active.
2907- assertNumHtlcs (t .t , alice , 4 )
2908- assertNumHtlcs (t .t , bob , 4 )
2916+ // At this point, both sides should have 4 (or +2 with MPP) HTLCs
2917+ // active.
2918+ numHtlcs := 4
2919+ if mpp {
2920+ numHtlcs += 2
2921+ }
2922+ assertNumHtlcs (t .t , alice , numHtlcs )
2923+ assertNumHtlcs (t .t , bob , numHtlcs )
29092924
29102925 // Before we force close, we'll grab the current height, the CSV delay
29112926 // needed, and also the absolute timeout of the set of active HTLCs.
@@ -2947,8 +2962,8 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29472962 // At this point, the commitment transaction has been mined, and we have
29482963 // 4 total HTLCs on Alice's commitment transaction:
29492964 //
2950- // * 2x outgoing HTLCs to Alice to Bob
2951- // * 2x incoming HTLCs from Bob to Alice
2965+ // * 2x outgoing HTLCs from Alice to Bob
2966+ // * 2x incoming HTLCs from Bob to Alice (+2 with MPP)
29522967 //
29532968 // We'll leave half the HTLCs timeout, while pulling the other half.
29542969 // To start, we'll signal Bob to settle one of his incoming HTLCs on
@@ -2971,7 +2986,7 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29712986 // We'll mine an empty block to get the sweeper to tick.
29722987 mineBlocks (t , net , 1 , 0 )
29732988
2974- sweepTx1 , err := waitForNTxsInMempool (
2989+ bobSweepTx1 , err := waitForNTxsInMempool (
29752990 net .Miner .Client , 1 , shortTimeout ,
29762991 )
29772992 require .NoError (t .t , err )
@@ -2984,15 +2999,17 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
29842999 // At this point, we should have the next sweep transaction in the
29853000 // mempool: Bob's incoming HTLC sweep directly off the commitment
29863001 // transaction.
2987- sweepTx2 , err := waitForNTxsInMempool (net .Miner .Client , 1 , shortTimeout )
3002+ bobSweepTx2 , err := waitForNTxsInMempool (
3003+ net .Miner .Client , 1 , shortTimeout ,
3004+ )
29883005 require .NoError (t .t , err )
29893006
29903007 // We'll now mine the next block, which should confirm Bob's HTLC sweep
29913008 // transaction.
29923009 mineBlocks (t , net , 1 , 1 )
29933010
2994- bobSweepTransfer1 := locateAssetTransfers (t .t , bobTap , * sweepTx1 [0 ])
2995- bobSweepTransfer2 := locateAssetTransfers (t .t , bobTap , * sweepTx2 [0 ])
3011+ bobSweepTransfer1 := locateAssetTransfers (t .t , bobTap , * bobSweepTx1 [0 ])
3012+ bobSweepTransfer2 := locateAssetTransfers (t .t , bobTap , * bobSweepTx2 [0 ])
29963013 t .Logf ("Bob's sweep transfer 1: %v" ,
29973014 toProtoJSON (t .t , bobSweepTransfer1 ))
29983015 t .Logf ("Bob's sweep transfer 2: %v" ,
@@ -3006,9 +3023,8 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30063023 // RFQ conversion.
30073024 bobExpectedBalance := closeExpiryInfo .remoteAssetBalance +
30083025 uint64 (assetInvoiceAmt - 1 )
3009- assertSpendableBalance (
3010- t .t , bobTap , assetID , bobExpectedBalance ,
3011- )
3026+ t .Logf ("Expecting Bob's balance to be %d" , bobExpectedBalance )
3027+ assertSpendableBalance (t .t , bobTap , assetID , bobExpectedBalance )
30123028
30133029 // With Bob's HTLC settled, we'll now have Alice do the same. For her,
30143030 // it'll be a 2nd level sweep, which requires an extra transaction.
@@ -3018,15 +3034,26 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30183034 // that she's swept everything properly. With the way the sweeper works,
30193035 // we need to mine one extra block before the sweeper picks things up.
30203036 mineBlocks (t , net , 1 , 0 )
3021- time .Sleep (time .Second * 1 )
3037+
3038+ aliceSweepTx1 , err := waitForNTxsInMempool (
3039+ net .Miner .Client , 1 , shortTimeout ,
3040+ )
3041+ require .NoError (t .t , err )
3042+
30223043 mineBlocks (t , net , 1 , 1 )
30233044
3045+ aliceSweepTransfer1 := locateAssetTransfers (
3046+ t .t , aliceTap , * aliceSweepTx1 [0 ],
3047+ )
3048+ t .Logf ("Alice's sweep transfer 1: %v" ,
3049+ toProtoJSON (t .t , aliceSweepTransfer1 ))
3050+
30243051 t .Logf ("Confirming Alice's to-local sweep" )
30253052
30263053 // With this extra block mined, Alice's settled balance should be the
30273054 // starting balance, minus the 2 HTLCs, plus her settled balance.
30283055 aliceExpectedBalance := itestAsset .Amount - fundingAmount
3029- aliceExpectedBalance += uint64 ( closeExpiryInfo .localAssetBalance )
3056+ aliceExpectedBalance += closeExpiryInfo .localAssetBalance
30303057 assertSpendableBalance (
30313058 t .t , aliceTap , assetID , aliceExpectedBalance ,
30323059 )
@@ -3056,9 +3083,27 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30563083 // If the block mined above didn't also mine our sweep, then we'll mine
30573084 // one final block which will confirm Alice's sweep transaction.
30583085 if len (sweepBlocks [0 ].Transactions ) == 1 {
3086+ sweepTx , err := waitForNTxsInMempool (
3087+ net .Miner .Client , 1 , shortTimeout ,
3088+ )
3089+ require .NoError (t .t , err )
3090+
30593091 // With the sweep transaction in the mempool, we'll mine a block
30603092 // to confirm the sweep.
30613093 mineBlocks (t , net , 1 , 1 )
3094+
3095+ aliceSweepTransfer := locateAssetTransfers (
3096+ t .t , aliceTap , * sweepTx [0 ],
3097+ )
3098+ t .Logf ("Alice's first-level sweep transfer: %v" ,
3099+ toProtoJSON (t .t , aliceSweepTransfer ))
3100+ } else {
3101+ sweepTx := sweepBlocks [0 ].Transactions [1 ]
3102+ aliceSweepTransfer := locateAssetTransfers (
3103+ t .t , aliceTap , sweepTx .TxHash (),
3104+ )
3105+ t .Logf ("Alice's first-level sweep transfer: %v" ,
3106+ toProtoJSON (t .t , aliceSweepTransfer ))
30623107 }
30633108
30643109 t .Logf ("Confirming Alice's second level remote HTLC success sweep" )
@@ -3085,7 +3130,25 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
30853130 // If the block mined above didn't also mine our sweep, then we'll mine
30863131 // one final block which will confirm Alice's sweep transaction.
30873132 if len (sweepBlocks [0 ].Transactions ) == 1 {
3133+ sweepTx , err := waitForNTxsInMempool (
3134+ net .Miner .Client , 1 , shortTimeout ,
3135+ )
3136+ require .NoError (t .t , err )
3137+
30883138 mineBlocks (t , net , 1 , 1 )
3139+
3140+ aliceSweepTransfer := locateAssetTransfers (
3141+ t .t , aliceTap , * sweepTx [0 ],
3142+ )
3143+ t .Logf ("Alice's second-level sweep transfer: %v" ,
3144+ toProtoJSON (t .t , aliceSweepTransfer ))
3145+ } else {
3146+ sweepTx := sweepBlocks [0 ].Transactions [1 ]
3147+ aliceSweepTransfer := locateAssetTransfers (
3148+ t .t , aliceTap , sweepTx .TxHash (),
3149+ )
3150+ t .Logf ("Alice's second-level sweep transfer: %v" ,
3151+ toProtoJSON (t .t , aliceSweepTransfer ))
30893152 }
30903153
30913154 // With the sweep transaction confirmed, Alice's balance should have
@@ -3153,14 +3216,33 @@ func testCustomChannelsHtlcForceClose(_ context.Context, net *NetworkHarness,
31533216 // If the block mined above didn't also mine our sweep, then we'll mine
31543217 // one final block which will confirm Alice's sweep transaction.
31553218 if len (sweepBlocks [0 ].Transactions ) == 1 {
3219+ sweepTx , err := waitForNTxsInMempool (
3220+ net .Miner .Client , 1 , shortTimeout ,
3221+ )
3222+ require .NoError (t .t , err )
3223+
31563224 // We'll mine one final block which will confirm Alice's sweep
31573225 // transaction.
31583226 mineBlocks (t , net , 1 , 1 )
3227+
3228+ aliceSweepTransfer := locateAssetTransfers (
3229+ t .t , aliceTap , * sweepTx [0 ],
3230+ )
3231+ t .Logf ("Alice's final timeout sweep transfer: %v" ,
3232+ toProtoJSON (t .t , aliceSweepTransfer ))
3233+ } else {
3234+ sweepTx := sweepBlocks [0 ].Transactions [1 ]
3235+ aliceSweepTransfer := locateAssetTransfers (
3236+ t .t , aliceTap , sweepTx .TxHash (),
3237+ )
3238+ t .Logf ("Alice's final timeout sweep transfer: %v" ,
3239+ toProtoJSON (t .t , aliceSweepTransfer ))
31593240 }
31603241
31613242 // Finally, we'll assert that Alice's balance has been incremented by
31623243 // the timeout value.
31633244 aliceExpectedBalance += uint64 (assetInvoiceAmt - 1 )
3245+ t .Logf ("Expecting Alice's balance to be %d" , aliceExpectedBalance )
31643246 assertSpendableBalance (
31653247 t .t , aliceTap , assetID , aliceExpectedBalance ,
31663248 )
0 commit comments