@@ -327,6 +327,21 @@ func (b *BudgetInputSet) copyInputs() []*SweeperInput {
327
327
return inputs
328
328
}
329
329
330
+ // hasNormalInput return a bool to indicate whether there exists an input that
331
+ // doesn't require a TxOut. When an input has no required outputs, it's either a
332
+ // wallet input, or an input we want to sweep.
333
+ func (b * BudgetInputSet ) hasNormalInput () bool {
334
+ for _ , inp := range b .inputs {
335
+ if inp .RequiredTxOut () != nil {
336
+ continue
337
+ }
338
+
339
+ return true
340
+ }
341
+
342
+ return false
343
+ }
344
+
330
345
// AddWalletInputs adds wallet inputs to the set until the specified budget is
331
346
// met. When sweeping inputs with required outputs, although there's budget
332
347
// specified, it cannot be directly spent from these required outputs. Instead,
@@ -350,11 +365,6 @@ func (b *BudgetInputSet) AddWalletInputs(wallet Wallet) error {
350
365
return fmt .Errorf ("list unspent witness: %w" , err )
351
366
}
352
367
353
- // Exit early if there are no wallet UTXOs.
354
- if len (utxos ) == 0 {
355
- return fmt .Errorf ("%w: empty wallet" , ErrNotEnoughInputs )
356
- }
357
-
358
368
// Sort the UTXOs by putting smaller values at the start of the slice
359
369
// to avoid locking large UTXO for sweeping.
360
370
//
@@ -377,8 +387,20 @@ func (b *BudgetInputSet) AddWalletInputs(wallet Wallet) error {
377
387
}
378
388
}
379
389
380
- log .Warn ("Not enough wallet UTXOs to cover the budget, sweeping " +
381
- "anyway..." )
390
+ // Exit if there are no inputs can contribute to the fees.
391
+ if ! b .hasNormalInput () {
392
+ return ErrNotEnoughInputs
393
+ }
394
+
395
+ // If there's at least one input that can contribute to fees, we allow
396
+ // the sweep to continue, even though the full budget can't be met.
397
+ // Maybe later more wallet inputs will become available and we can add
398
+ // them if needed.
399
+ budget := b .Budget ()
400
+ total , spendable := b .inputAmts ()
401
+ log .Warnf ("Not enough wallet UTXOs: need budget=%v, has spendable=%v, " +
402
+ "total=%v, missing at least %v, sweeping anyway..." , budget ,
403
+ spendable , total , budget - spendable )
382
404
383
405
return nil
384
406
}
@@ -416,6 +438,28 @@ func (b *BudgetInputSet) Inputs() []input.Input {
416
438
return inputs
417
439
}
418
440
441
+ // inputAmts returns two values for the set - the total input amount, and the
442
+ // spendable amount. Only the spendable amount can be used to pay the fees.
443
+ func (b * BudgetInputSet ) inputAmts () (btcutil.Amount , btcutil.Amount ) {
444
+ var (
445
+ totalAmt btcutil.Amount
446
+ spendableAmt btcutil.Amount
447
+ )
448
+
449
+ for _ , inp := range b .inputs {
450
+ output := btcutil .Amount (inp .SignDesc ().Output .Value )
451
+ totalAmt += output
452
+
453
+ if inp .RequiredTxOut () != nil {
454
+ continue
455
+ }
456
+
457
+ spendableAmt += output
458
+ }
459
+
460
+ return totalAmt , spendableAmt
461
+ }
462
+
419
463
// StartingFeeRate returns the max starting fee rate found in the inputs.
420
464
//
421
465
// NOTE: part of the InputSet interface.
0 commit comments