Skip to content

Commit 55c3da3

Browse files
committed
lnwallet+lnrpc: use maxFeeRatio across coin selection tests
1 parent f2b7632 commit 55c3da3

File tree

2 files changed

+135
-11
lines changed

2 files changed

+135
-11
lines changed

lnrpc/walletrpc/walletkit_server_test.go

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,18 @@ func TestFundPsbtCoinSelect(t *testing.T) {
162162
// packet in bytes.
163163
expectedFee btcutil.Amount
164164

165+
// maxFeeRatio is the maximum fee to total output amount ratio
166+
// that we consider valid.
167+
maxFeeRatio float64
168+
165169
// expectedErr is the expected concrete error. If not nil, then
166170
// the error must match exactly.
167171
expectedErr error
168172

173+
// expectedContainedErrStr is the expected string to be
174+
// contained in the returned error.
175+
expectedContainedErrStr string
176+
169177
// expectedErrType is the expected error type. If not nil, then
170178
// the error must be of this type.
171179
expectedErrType error
@@ -178,6 +186,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
178186
}),
179187
changeIndex: -1,
180188
feeRate: chainfee.FeePerKwFloor,
189+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
181190
expectedErrType: &chanfunding.ErrInsufficientFunds{},
182191
}, {
183192
name: "1 p2wpkh utxo, add p2wkh change",
@@ -193,6 +202,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
193202
}),
194203
changeIndex: -1,
195204
feeRate: chainfee.FeePerKwFloor,
205+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
196206
expectedUtxoIndexes: []int{0},
197207
expectChangeOutputIndex: 1,
198208
expectedFee: calcFee(0, 1, 1, 1, 0),
@@ -210,6 +220,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
210220
}),
211221
changeIndex: -1,
212222
feeRate: chainfee.FeePerKwFloor,
223+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
213224
changeType: chanfunding.P2TRChangeAddress,
214225
expectedUtxoIndexes: []int{0},
215226
expectChangeOutputIndex: 1,
@@ -228,6 +239,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
228239
}),
229240
changeIndex: -1,
230241
feeRate: chainfee.FeePerKwFloor,
242+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
231243
expectedUtxoIndexes: []int{0},
232244
expectChangeOutputIndex: -1,
233245
expectedFee: calcFee(0, 1, 1, 0, 0),
@@ -247,6 +259,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
247259
}),
248260
changeIndex: -1,
249261
feeRate: chainfee.FeePerKwFloor,
262+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
250263
changeType: chanfunding.P2WKHChangeAddress,
251264
expectedUtxoIndexes: []int{0},
252265
expectChangeOutputIndex: -1,
@@ -267,6 +280,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
267280
}),
268281
changeIndex: -1,
269282
feeRate: chainfee.FeePerKwFloor,
283+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
270284
changeType: chanfunding.P2TRChangeAddress,
271285
expectedUtxoIndexes: []int{0},
272286
expectChangeOutputIndex: -1,
@@ -285,6 +299,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
285299
}),
286300
changeIndex: 0,
287301
feeRate: chainfee.FeePerKwFloor,
302+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
288303
changeType: chanfunding.ExistingChangeAddress,
289304
expectedUtxoIndexes: []int{0},
290305
expectChangeOutputIndex: 0,
@@ -303,6 +318,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
303318
}),
304319
changeIndex: 0,
305320
feeRate: chainfee.FeePerKwFloor,
321+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
306322
changeType: chanfunding.ExistingChangeAddress,
307323
expectedUtxoIndexes: []int{0},
308324
expectChangeOutputIndex: 0,
@@ -321,6 +337,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
321337
}),
322338
changeIndex: 0,
323339
feeRate: chainfee.FeePerKwFloor,
340+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
324341
changeType: chanfunding.ExistingChangeAddress,
325342
expectedUtxoIndexes: []int{0},
326343
expectChangeOutputIndex: 0,
@@ -369,6 +386,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
369386
}),
370387
changeIndex: 0,
371388
feeRate: chainfee.FeePerKwFloor,
389+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
372390
changeType: chanfunding.ExistingChangeAddress,
373391
expectedUtxoIndexes: []int{0, 1},
374392
expectChangeOutputIndex: 0,
@@ -417,6 +435,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
417435
}),
418436
changeIndex: -1,
419437
feeRate: chainfee.FeePerKwFloor,
438+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
420439
changeType: chanfunding.P2TRChangeAddress,
421440
expectedUtxoIndexes: []int{0, 1},
422441
expectChangeOutputIndex: 1,
@@ -456,6 +475,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
456475
}),
457476
changeIndex: -1,
458477
feeRate: chainfee.FeePerKwFloor,
478+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
459479
changeType: chanfunding.P2WKHChangeAddress,
460480
expectedUtxoIndexes: []int{},
461481
expectChangeOutputIndex: 1,
@@ -497,10 +517,74 @@ func TestFundPsbtCoinSelect(t *testing.T) {
497517
}),
498518
changeIndex: -1,
499519
feeRate: chainfee.FeePerKwFloor,
520+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
500521
changeType: chanfunding.P2TRChangeAddress,
501522
expectedUtxoIndexes: []int{},
502523
expectChangeOutputIndex: -1,
503524
expectedFee: calcFee(1, 0, 1, 0, 0),
525+
}, {
526+
name: "1 p2wpkh utxo, existing p2wkh change, invalid fee ratio",
527+
utxos: []*lnwallet.Utxo{
528+
{
529+
Value: 250,
530+
PkScript: p2wkhScript,
531+
},
532+
},
533+
packet: makePacket(&wire.TxOut{
534+
Value: 50,
535+
PkScript: p2wkhScript,
536+
}),
537+
changeIndex: 0,
538+
feeRate: chainfee.FeePerKwFloor,
539+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
540+
changeType: chanfunding.ExistingChangeAddress,
541+
expectedUtxoIndexes: []int{0},
542+
expectChangeOutputIndex: 0,
543+
expectedFee: calcFee(0, 1, 0, 1, 0),
544+
545+
expectedContainedErrStr: "fee 0.00000111 BTC exceeds max fee " +
546+
"(0.00000027 BTC) on total output value",
547+
}, {
548+
name: "1 p2wpkh utxo, existing p2wkh change, negative feeratio",
549+
utxos: []*lnwallet.Utxo{
550+
{
551+
Value: 250,
552+
PkScript: p2wkhScript,
553+
},
554+
},
555+
packet: makePacket(&wire.TxOut{
556+
Value: 50,
557+
PkScript: p2wkhScript,
558+
}),
559+
changeIndex: 0,
560+
feeRate: chainfee.FeePerKwFloor,
561+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio * (-1),
562+
changeType: chanfunding.ExistingChangeAddress,
563+
expectedUtxoIndexes: []int{0},
564+
expectChangeOutputIndex: 0,
565+
expectedFee: calcFee(0, 1, 0, 1, 0),
566+
567+
expectedContainedErrStr: "maxFeeRatio must be between 0.00 " +
568+
"and 1.00 got -0.20",
569+
}, {
570+
name: "1 p2wpkh utxo, existing p2wkh change, big fee ratio",
571+
utxos: []*lnwallet.Utxo{
572+
{
573+
Value: 250,
574+
PkScript: p2wkhScript,
575+
},
576+
},
577+
packet: makePacket(&wire.TxOut{
578+
Value: 50,
579+
PkScript: p2wkhScript,
580+
}),
581+
changeIndex: 0,
582+
feeRate: chainfee.FeePerKwFloor,
583+
maxFeeRatio: 0.85,
584+
changeType: chanfunding.ExistingChangeAddress,
585+
expectedUtxoIndexes: []int{0},
586+
expectChangeOutputIndex: 0,
587+
expectedFee: calcFee(0, 1, 0, 1, 0),
504588
}, {
505589
name: "large existing p2tr input, fee estimation existing " +
506590
"change output",
@@ -536,6 +620,7 @@ func TestFundPsbtCoinSelect(t *testing.T) {
536620
}),
537621
changeIndex: 0,
538622
feeRate: chainfee.FeePerKwFloor,
623+
maxFeeRatio: chanfunding.DefaultMaxFeeRatio,
539624
changeType: chanfunding.ExistingChangeAddress,
540625
expectedUtxoIndexes: []int{},
541626
expectChangeOutputIndex: 0,
@@ -574,7 +659,8 @@ func TestFundPsbtCoinSelect(t *testing.T) {
574659
resp, err := rpcServer.fundPsbtCoinSelect(
575660
"", tc.changeIndex, copiedPacket, 0,
576661
tc.changeType, tc.feeRate,
577-
rpcServer.cfg.CoinSelectionStrategy, 0,
662+
rpcServer.cfg.CoinSelectionStrategy,
663+
tc.maxFeeRatio,
578664
)
579665

580666
switch {
@@ -588,6 +674,12 @@ func TestFundPsbtCoinSelect(t *testing.T) {
588674
require.Error(tt, err)
589675
require.ErrorAs(tt, err, &tc.expectedErr)
590676

677+
return
678+
case tc.expectedContainedErrStr != "":
679+
require.ErrorContains(
680+
tt, err, tc.expectedContainedErrStr,
681+
)
682+
591683
return
592684
}
593685

lnwallet/chanfunding/coin_select_test.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ func TestCoinSelect(t *testing.T) {
316316
selected, changeAmt, err := CoinSelect(
317317
feeRate, test.outputValue, dustLimit,
318318
test.coins, wallet.CoinSelectionLargest,
319-
fundingOutputEstimate, test.changeType, 0,
319+
fundingOutputEstimate, test.changeType,
320+
DefaultMaxFeeRatio,
320321
)
321322

322323
if test.expectErr {
@@ -356,6 +357,7 @@ func TestCalculateChangeAmount(t *testing.T) {
356357
feeWithChange btcutil.Amount
357358
dustLimit btcutil.Amount
358359
changeType ChangeAddressType
360+
maxFeeRatio float64
359361

360362
expectErr string
361363
expectChangeAmt btcutil.Amount
@@ -369,6 +371,7 @@ func TestCalculateChangeAmount(t *testing.T) {
369371
totalInputAmt: 500,
370372
requiredAmt: 490,
371373
feeNoChange: 12,
374+
maxFeeRatio: DefaultMaxFeeRatio,
372375

373376
expectNeedMore: 502,
374377
}, {
@@ -383,6 +386,7 @@ func TestCalculateChangeAmount(t *testing.T) {
383386
feeWithChange: 10,
384387
dustLimit: 100,
385388
changeType: ExistingChangeAddress,
389+
maxFeeRatio: DefaultMaxFeeRatio,
386390

387391
expectChangeAmt: 90,
388392
}, {
@@ -392,6 +396,7 @@ func TestCalculateChangeAmount(t *testing.T) {
392396
feeNoChange: 40,
393397
feeWithChange: 50,
394398
dustLimit: 100,
399+
maxFeeRatio: DefaultMaxFeeRatio,
395400

396401
expectChangeAmt: 150,
397402
}, {
@@ -401,6 +406,7 @@ func TestCalculateChangeAmount(t *testing.T) {
401406
requiredAmt: 460,
402407
feeNoChange: 40,
403408
feeWithChange: 50,
409+
maxFeeRatio: DefaultMaxFeeRatio,
404410

405411
expectChangeAmt: 0,
406412
}, {
@@ -410,14 +416,36 @@ func TestCalculateChangeAmount(t *testing.T) {
410416
feeNoChange: 10,
411417
feeWithChange: 45,
412418
dustLimit: 5,
419+
maxFeeRatio: DefaultMaxFeeRatio,
413420

414-
expectErr: "fee (0.00000045 BTC) exceeds 20% of total output " +
415-
"(0.00000055 BTC)",
421+
expectErr: "fee 0.00000045 BTC exceeds max fee (0.00000011 " +
422+
"BTC) on total output value 0.00000055 BTC",
423+
}, {
424+
name: "fee percent ok",
425+
totalInputAmt: 100,
426+
requiredAmt: 50,
427+
feeNoChange: 10,
428+
feeWithChange: 45,
429+
dustLimit: 5,
430+
maxFeeRatio: 0.95,
431+
432+
expectChangeAmt: 5,
433+
}, {
434+
name: "invalid max fee ratio",
435+
totalInputAmt: 100,
436+
requiredAmt: 50,
437+
feeNoChange: 10,
438+
feeWithChange: 45,
439+
dustLimit: 5,
440+
maxFeeRatio: 3.14,
441+
442+
expectErr: "maxFeeRatio must be between 0.00 and 1.00",
416443
}, {
417444
name: "invalid usage of function",
418445
feeNoChange: 5,
419446
feeWithChange: 10,
420447
changeType: ExistingChangeAddress,
448+
maxFeeRatio: DefaultMaxFeeRatio,
421449

422450
expectErr: "fees for with or without change must be the same",
423451
}}
@@ -428,7 +456,7 @@ func TestCalculateChangeAmount(t *testing.T) {
428456
changeAmt, needMore, err := CalculateChangeAmount(
429457
tc.totalInputAmt, tc.requiredAmt,
430458
tc.feeNoChange, tc.feeWithChange, tc.dustLimit,
431-
tc.changeType, 0,
459+
tc.changeType, tc.maxFeeRatio,
432460
)
433461

434462
if tc.expectErr != "" {
@@ -606,8 +634,9 @@ func TestCoinSelectSubtractFees(t *testing.T) {
606634
},
607635
spendValue: 5 * fundingFee(highFeeRate, 1, false),
608636

609-
expectErr: "fee (<amt> BTC) exceeds <amt>% of total " +
610-
"output (<amt> BTC)",
637+
expectErr: "fee <amt> BTC exceeds max fee (<amt> " +
638+
"BTC) on total output value <amt> BTC with " +
639+
"max fee ratio of <amt>",
611640
},
612641
}
613642

@@ -627,7 +656,8 @@ func TestCoinSelectSubtractFees(t *testing.T) {
627656
feeRate, test.spendValue, dustLimit, test.coins,
628657
wallet.CoinSelectionLargest,
629658
fundingOutputEstimate,
630-
defaultChanFundingChangeType, 0,
659+
defaultChanFundingChangeType,
660+
DefaultMaxFeeRatio,
631661
)
632662
if err != nil {
633663
switch {
@@ -813,8 +843,9 @@ func TestCoinSelectUpToAmount(t *testing.T) {
813843
minValue: minValue,
814844
maxValue: 16 * fundingFee(feeRate, 1, false),
815845

816-
expectErr: "fee (0.00000192 BTC) exceeds 20% of total output " +
817-
"(0.00000768 BTC)",
846+
expectErr: "fee 0.00000192 BTC exceeds max fee (0.00000153 " +
847+
"BTC) on total output value 0.00000768 BTC with max " +
848+
"fee ratio of 0.20",
818849
}, {
819850
// This test makes sure that the implementation detail of using
820851
// CoinSelect and CoinSelectSubtractFees is done correctly.
@@ -872,7 +903,8 @@ func TestCoinSelectUpToAmount(t *testing.T) {
872903
test.reserved, dustLimit, test.coins,
873904
wallet.CoinSelectionLargest,
874905
fundingOutputEstimate,
875-
defaultChanFundingChangeType, 0,
906+
defaultChanFundingChangeType,
907+
DefaultMaxFeeRatio,
876908
)
877909
if len(test.expectErr) == 0 && err != nil {
878910
t.Fatal(err.Error())

0 commit comments

Comments
 (0)