66 "github.com/btcsuite/btcd/btcutil"
77 "github.com/btcsuite/btcd/chaincfg"
88 "github.com/btcsuite/btcd/chaincfg/chainhash"
9+ "github.com/btcsuite/btcd/txscript"
910 "github.com/btcsuite/btcd/wire"
1011 "github.com/lightninglabs/loop/swap"
1112 "github.com/lightningnetwork/lnd/input"
@@ -16,24 +17,29 @@ import (
1617
1718// Useful constants for tests.
1819const (
19- lowFeeRate = chainfee .FeePerKwFloor
20- highFeeRate = chainfee .SatPerKWeight (30000 )
20+ lowFeeRate = chainfee .FeePerKwFloor
21+ mediumFeeRate = lowFeeRate + 200
22+ highFeeRate = chainfee .SatPerKWeight (30000 )
2123
2224 coopInputWeight = lntypes .WeightUnit (230 )
25+ batchOutputWeight = lntypes .WeightUnit (343 )
2326 nonCoopInputWeight = lntypes .WeightUnit (393 )
2427 nonCoopPenalty = nonCoopInputWeight - coopInputWeight
2528 coopNewBatchWeight = lntypes .WeightUnit (444 )
2629 nonCoopNewBatchWeight = coopNewBatchWeight + nonCoopPenalty
30+ changeOutputWeight = lntypes .WeightUnit (input .P2TROutputSize )
2731
2832 // p2pkhDiscount is weight discount P2PKH output has over P2TR output.
2933 p2pkhDiscount = lntypes .WeightUnit (
3034 input .P2TROutputSize - input .P2PKHOutputSize ,
3135 ) * 4
3236
33- coopTwoSweepBatchWeight = coopNewBatchWeight + coopInputWeight
34- nonCoopTwoSweepBatchWeight = coopTwoSweepBatchWeight + 2 * nonCoopPenalty
35- v2v3BatchWeight = nonCoopTwoSweepBatchWeight - 25
36- mixedTwoSweepBatchWeight = coopTwoSweepBatchWeight + nonCoopPenalty
37+ coopTwoSweepBatchWeight = coopNewBatchWeight + coopInputWeight
38+ coopSingleSweepChangeBatchWeight = coopInputWeight + batchOutputWeight + changeOutputWeight
39+ coopDoubleSweepChangeBatchWeight = 2 * coopInputWeight + batchOutputWeight + changeOutputWeight
40+ nonCoopTwoSweepBatchWeight = coopTwoSweepBatchWeight + 2 * nonCoopPenalty
41+ v2v3BatchWeight = nonCoopTwoSweepBatchWeight - 25
42+ mixedTwoSweepBatchWeight = coopTwoSweepBatchWeight + nonCoopPenalty
3743)
3844
3945// testHtlcV2SuccessEstimator adds weight of non-cooperative input to estimator
@@ -265,6 +271,13 @@ func TestEstimateBatchWeight(t *testing.T) {
265271 se3 := testHtlcV3SuccessEstimator
266272 trAddr := (* btcutil .AddressTaproot )(nil )
267273
274+ changeAddr := "bc1pdx9ggvtjjcpaqfqk375qhdmzx9xu8dcu7w94lqfcxhh0rj" +
275+ "lwyyeq5ryn6r"
276+ changeAddress , err := btcutil .DecodeAddress (changeAddr , nil )
277+ require .NoError (t , err )
278+ changePkscript , err := txscript .PayToAddrScript (changeAddress )
279+ require .NoError (t , err )
280+
268281 cases := []struct {
269282 name string
270283 batch * batch
@@ -290,6 +303,58 @@ func TestEstimateBatchWeight(t *testing.T) {
290303 },
291304 },
292305
306+ {
307+ name : "one sweep regular batch with change" ,
308+ batch : & batch {
309+ id : 1 ,
310+ rbfCache : rbfCache {
311+ FeeRate : lowFeeRate ,
312+ },
313+ sweeps : map [wire.OutPoint ]sweep {
314+ outpoint1 : {
315+ htlcSuccessEstimator : se3 ,
316+ change : & wire.TxOut {
317+ PkScript : changePkscript ,
318+ },
319+ },
320+ },
321+ },
322+ wantBatchFeeDetails : feeDetails {
323+ BatchId : 1 ,
324+ FeeRate : lowFeeRate ,
325+ Weight : coopSingleSweepChangeBatchWeight ,
326+ },
327+ },
328+
329+ {
330+ name : "two sweeps regular batch with identical change" ,
331+ batch : & batch {
332+ id : 1 ,
333+ rbfCache : rbfCache {
334+ FeeRate : lowFeeRate ,
335+ },
336+ sweeps : map [wire.OutPoint ]sweep {
337+ outpoint1 : {
338+ htlcSuccessEstimator : se3 ,
339+ change : & wire.TxOut {
340+ PkScript : changePkscript ,
341+ },
342+ },
343+ outpoint2 : {
344+ htlcSuccessEstimator : se3 ,
345+ change : & wire.TxOut {
346+ PkScript : changePkscript ,
347+ },
348+ },
349+ },
350+ },
351+ wantBatchFeeDetails : feeDetails {
352+ BatchId : 1 ,
353+ FeeRate : lowFeeRate ,
354+ Weight : coopDoubleSweepChangeBatchWeight ,
355+ },
356+ },
357+
293358 {
294359 name : "two sweeps regular batch" ,
295360 batch : & batch {
@@ -778,6 +843,47 @@ func TestSelectBatches(t *testing.T) {
778843 },
779844 wantBestBatchesIds : []int32 {1 , newBatchSignal },
780845 },
846+
847+ {
848+ name : "low fee change sweep, placed in new batch" ,
849+ batches : []feeDetails {
850+ {
851+ BatchId : 1 ,
852+ FeeRate : mediumFeeRate ,
853+ Weight : coopNewBatchWeight ,
854+ },
855+ },
856+ sweep : feeDetails {
857+ FeeRate : lowFeeRate ,
858+ Weight : coopInputWeight + changeOutputWeight ,
859+ },
860+ oneSweepBatch : feeDetails {
861+ FeeRate : lowFeeRate ,
862+ Weight : coopNewBatchWeight ,
863+ },
864+ wantBestBatchesIds : []int32 {newBatchSignal , 1 },
865+ },
866+
867+ {
868+ name : "low fee sweep without change, placed in " +
869+ "existing batch" ,
870+ batches : []feeDetails {
871+ {
872+ BatchId : 1 ,
873+ FeeRate : mediumFeeRate ,
874+ Weight : coopNewBatchWeight ,
875+ },
876+ },
877+ sweep : feeDetails {
878+ FeeRate : lowFeeRate ,
879+ Weight : coopInputWeight ,
880+ },
881+ oneSweepBatch : feeDetails {
882+ FeeRate : lowFeeRate ,
883+ Weight : coopNewBatchWeight ,
884+ },
885+ wantBestBatchesIds : []int32 {1 , newBatchSignal },
886+ },
781887 }
782888
783889 for _ , tc := range cases {
0 commit comments