Skip to content

Commit 4cb5c2c

Browse files
committed
sweepbatcher: consider optional change in greedy selection
1 parent 6bedd9e commit 4cb5c2c

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

sweepbatcher/greedy_batch_selection.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,13 @@ func estimateBatchWeight(batch *batch) (feeDetails, error) {
210210
err)
211211
}
212212

213+
// Add change output weights.
214+
for _, s := range batch.sweeps {
215+
if s.change != nil {
216+
weight.AddOutput(s.change.PkScript)
217+
}
218+
}
219+
213220
// Add inputs.
214221
for _, sweep := range batch.sweeps {
215222
if sweep.nonCoopHint || sweep.coopFailed {

sweepbatcher/greedy_batch_selection_test.go

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
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,28 @@ import (
1617

1718
// Useful constants for tests.
1819
const (
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+
nonCoopTwoSweepBatchWeight = coopTwoSweepBatchWeight + 2*nonCoopPenalty
40+
v2v3BatchWeight = nonCoopTwoSweepBatchWeight - 25
41+
mixedTwoSweepBatchWeight = coopTwoSweepBatchWeight + nonCoopPenalty
3742
)
3843

3944
// testHtlcV2SuccessEstimator adds weight of non-cooperative input to estimator
@@ -265,6 +270,13 @@ func TestEstimateBatchWeight(t *testing.T) {
265270
se3 := testHtlcV3SuccessEstimator
266271
trAddr := (*btcutil.AddressTaproot)(nil)
267272

273+
changeAddr := "bc1pdx9ggvtjjcpaqfqk375qhdmzx9xu8dcu7w94lqfcxhh0rj" +
274+
"lwyyeq5ryn6r"
275+
changeAddress, err := btcutil.DecodeAddress(changeAddr, nil)
276+
require.NoError(t, err)
277+
changePkscript, err := txscript.PayToAddrScript(changeAddress)
278+
require.NoError(t, err)
279+
268280
cases := []struct {
269281
name string
270282
batch *batch
@@ -290,6 +302,29 @@ func TestEstimateBatchWeight(t *testing.T) {
290302
},
291303
},
292304

305+
{
306+
name: "one sweep regular batch with change",
307+
batch: &batch{
308+
id: 1,
309+
rbfCache: rbfCache{
310+
FeeRate: lowFeeRate,
311+
},
312+
sweeps: map[wire.OutPoint]sweep{
313+
outpoint1: {
314+
htlcSuccessEstimator: se3,
315+
change: &wire.TxOut{
316+
PkScript: changePkscript,
317+
},
318+
},
319+
},
320+
},
321+
wantBatchFeeDetails: feeDetails{
322+
BatchId: 1,
323+
FeeRate: lowFeeRate,
324+
Weight: coopSingleSweepChangeBatchWeight,
325+
},
326+
},
327+
293328
{
294329
name: "two sweeps regular batch",
295330
batch: &batch{
@@ -778,6 +813,47 @@ func TestSelectBatches(t *testing.T) {
778813
},
779814
wantBestBatchesIds: []int32{1, newBatchSignal},
780815
},
816+
817+
{
818+
name: "low fee change sweep, placed in new batch",
819+
batches: []feeDetails{
820+
{
821+
BatchId: 1,
822+
FeeRate: mediumFeeRate,
823+
Weight: coopNewBatchWeight,
824+
},
825+
},
826+
sweep: feeDetails{
827+
FeeRate: lowFeeRate,
828+
Weight: coopInputWeight + changeOutputWeight,
829+
},
830+
oneSweepBatch: feeDetails{
831+
FeeRate: lowFeeRate,
832+
Weight: coopNewBatchWeight,
833+
},
834+
wantBestBatchesIds: []int32{newBatchSignal, 1},
835+
},
836+
837+
{
838+
name: "high fee change sweep, placed in existing " +
839+
"medium batch",
840+
batches: []feeDetails{
841+
{
842+
BatchId: 1,
843+
FeeRate: mediumFeeRate,
844+
Weight: coopNewBatchWeight,
845+
},
846+
},
847+
sweep: feeDetails{
848+
FeeRate: highFeeRate,
849+
Weight: coopInputWeight + changeOutputWeight,
850+
},
851+
oneSweepBatch: feeDetails{
852+
FeeRate: highFeeRate,
853+
Weight: coopNewBatchWeight,
854+
},
855+
wantBestBatchesIds: []int32{newBatchSignal, 1},
856+
},
781857
}
782858

783859
for _, tc := range cases {

0 commit comments

Comments
 (0)