6
6
"github.com/btcsuite/btcd/btcutil"
7
7
"github.com/btcsuite/btcd/chaincfg"
8
8
"github.com/btcsuite/btcd/chaincfg/chainhash"
9
+ "github.com/btcsuite/btcd/txscript"
9
10
"github.com/btcsuite/btcd/wire"
10
11
"github.com/lightninglabs/loop/swap"
11
12
"github.com/lightningnetwork/lnd/input"
@@ -16,24 +17,29 @@ import (
16
17
17
18
// Useful constants for tests.
18
19
const (
19
- lowFeeRate = chainfee .FeePerKwFloor
20
- highFeeRate = chainfee .SatPerKWeight (30000 )
20
+ lowFeeRate = chainfee .FeePerKwFloor
21
+ mediumFeeRate = lowFeeRate + 200
22
+ highFeeRate = chainfee .SatPerKWeight (30000 )
21
23
22
24
coopInputWeight = lntypes .WeightUnit (230 )
25
+ batchOutputWeight = lntypes .WeightUnit (343 )
23
26
nonCoopInputWeight = lntypes .WeightUnit (393 )
24
27
nonCoopPenalty = nonCoopInputWeight - coopInputWeight
25
28
coopNewBatchWeight = lntypes .WeightUnit (444 )
26
29
nonCoopNewBatchWeight = coopNewBatchWeight + nonCoopPenalty
30
+ changeOutputWeight = lntypes .WeightUnit (input .P2TROutputSize )
27
31
28
32
// p2pkhDiscount is weight discount P2PKH output has over P2TR output.
29
33
p2pkhDiscount = lntypes .WeightUnit (
30
34
input .P2TROutputSize - input .P2PKHOutputSize ,
31
35
) * 4
32
36
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
37
43
)
38
44
39
45
// testHtlcV2SuccessEstimator adds weight of non-cooperative input to estimator
@@ -265,6 +271,13 @@ func TestEstimateBatchWeight(t *testing.T) {
265
271
se3 := testHtlcV3SuccessEstimator
266
272
trAddr := (* btcutil .AddressTaproot )(nil )
267
273
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
+
268
281
cases := []struct {
269
282
name string
270
283
batch * batch
@@ -290,6 +303,58 @@ func TestEstimateBatchWeight(t *testing.T) {
290
303
},
291
304
},
292
305
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
+
293
358
{
294
359
name : "two sweeps regular batch" ,
295
360
batch : & batch {
@@ -778,6 +843,47 @@ func TestSelectBatches(t *testing.T) {
778
843
},
779
844
wantBestBatchesIds : []int32 {1 , newBatchSignal },
780
845
},
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
+ },
781
887
}
782
888
783
889
for _ , tc := range cases {
0 commit comments