mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-18 13:27:56 +01:00
multi: Add utxo restriction for batchchannel openings.
Add utxo restrictions for psbt internal wallet funded lightning channels. This also includes batchopening channels backed by the internal wallet.
This commit is contained in:
parent
62a52b4d7c
commit
ab7634b276
@ -1551,21 +1551,82 @@ func (w *WalletKit) fundPsbtInternalWallet(account string,
|
||||
return err
|
||||
}
|
||||
|
||||
// filterFn makes sure utxos which are unconfirmed and
|
||||
// still used by the sweeper are not used.
|
||||
filterFn := func(u *lnwallet.Utxo) bool {
|
||||
// Confirmed utxos are always allowed.
|
||||
if u.Confirmations > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// Unconfirmed utxos in use by the sweeper are
|
||||
// not stable to use because they can be
|
||||
// replaced.
|
||||
if w.cfg.Sweeper.IsSweeperOutpoint(u.OutPoint) {
|
||||
log.Warnf("Cannot use unconfirmed "+
|
||||
"utxo=%v because it is "+
|
||||
"unstable and could be "+
|
||||
"replaced", u.OutPoint)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
eligible := fn.Filter(filterFn, utxos)
|
||||
|
||||
// Validate all inputs against our known list of UTXOs
|
||||
// now.
|
||||
err = verifyInputsUnspent(packet.UnsignedTx.TxIn, utxos)
|
||||
err = verifyInputsUnspent(
|
||||
packet.UnsignedTx.TxIn, eligible,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// currentHeight is needed to determine whether the internal
|
||||
// wallet utxo is still unconfirmed.
|
||||
_, currentHeight, err := w.cfg.Chain.GetBestBlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve current "+
|
||||
"height: %v", err)
|
||||
}
|
||||
|
||||
// restrictUnstableUtxos is a filter function which disallows
|
||||
// the usage of unconfirmed outputs published (still in use) by
|
||||
// the sweeper.
|
||||
restrictUnstableUtxos := func(utxo wtxmgr.Credit) bool {
|
||||
// Wallet utxos which are unmined have a height
|
||||
// of -1.
|
||||
if utxo.Height != -1 && utxo.Height <= currentHeight {
|
||||
// Confirmed utxos are always allowed.
|
||||
return true
|
||||
}
|
||||
|
||||
// Utxos used by the sweeper are not used for
|
||||
// channel openings.
|
||||
allowed := !w.cfg.Sweeper.IsSweeperOutpoint(
|
||||
utxo.OutPoint,
|
||||
)
|
||||
if !allowed {
|
||||
log.Warnf("Cannot use unconfirmed "+
|
||||
"utxo=%v because it is "+
|
||||
"unstable and could be "+
|
||||
"replaced", utxo.OutPoint)
|
||||
}
|
||||
|
||||
return allowed
|
||||
}
|
||||
|
||||
// We made sure the input from the user is as sane as possible.
|
||||
// We can now ask the wallet to fund the TX. This will not yet
|
||||
// lock any coins but might still change the wallet DB by
|
||||
// generating a new change address.
|
||||
changeIndex, err := w.cfg.Wallet.FundPsbt(
|
||||
packet, minConfs, feeSatPerKW, account,
|
||||
keyScope, strategy,
|
||||
packet, minConfs, feeSatPerKW, account, keyScope,
|
||||
strategy, restrictUnstableUtxos,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("wallet couldn't fund PSBT: %w", err)
|
||||
|
@ -208,7 +208,8 @@ func (w *WalletController) ListLeasedOutputs() ([]*base.ListLeasedOutputResult,
|
||||
|
||||
// FundPsbt currently does nothing.
|
||||
func (w *WalletController) FundPsbt(*psbt.Packet, int32, chainfee.SatPerKWeight,
|
||||
string, *waddrmgr.KeyScope, base.CoinSelectionStrategy) (int32, error) {
|
||||
string, *waddrmgr.KeyScope, base.CoinSelectionStrategy,
|
||||
func(utxo wtxmgr.Credit) bool) (int32, error) {
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
"github.com/btcsuite/btcwallet/wallet"
|
||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
@ -60,6 +61,9 @@ var (
|
||||
// imported public keys. For custom account, no key scope should be provided
|
||||
// as the coin selection key scope will always be used to generate the change
|
||||
// address.
|
||||
// The function argument `allowUtxo` specifies a filter function for utxos
|
||||
// during coin selection. It should return true for utxos that can be used and
|
||||
// false for those that should be excluded.
|
||||
//
|
||||
// NOTE: If the packet doesn't contain any inputs, coin selection is performed
|
||||
// automatically. The account parameter must be non-empty as it determines which
|
||||
@ -74,7 +78,8 @@ var (
|
||||
func (b *BtcWallet) FundPsbt(packet *psbt.Packet, minConfs int32,
|
||||
feeRate chainfee.SatPerKWeight, accountName string,
|
||||
changeScope *waddrmgr.KeyScope,
|
||||
strategy wallet.CoinSelectionStrategy) (int32, error) {
|
||||
strategy wallet.CoinSelectionStrategy,
|
||||
allowUtxo func(wtxmgr.Credit) bool) (int32, error) {
|
||||
|
||||
// The fee rate is passed in using units of sat/kw, so we'll convert
|
||||
// this to sat/KB as the CreateSimpleTx method requires this unit.
|
||||
@ -130,6 +135,9 @@ func (b *BtcWallet) FundPsbt(packet *psbt.Packet, minConfs int32,
|
||||
if changeScope != nil {
|
||||
opts = append(opts, wallet.WithCustomChangeScope(changeScope))
|
||||
}
|
||||
if allowUtxo != nil {
|
||||
opts = append(opts, wallet.WithUtxoFilter(allowUtxo))
|
||||
}
|
||||
|
||||
// Let the wallet handle coin selection and/or fee estimation based on
|
||||
// the partial TX information in the packet.
|
||||
|
@ -468,7 +468,8 @@ type WalletController interface {
|
||||
FundPsbt(packet *psbt.Packet, minConfs int32,
|
||||
feeRate chainfee.SatPerKWeight, account string,
|
||||
changeScope *waddrmgr.KeyScope,
|
||||
strategy base.CoinSelectionStrategy) (int32, error)
|
||||
strategy base.CoinSelectionStrategy,
|
||||
allowUtxo func(wtxmgr.Credit) bool) (int32, error)
|
||||
|
||||
// SignPsbt expects a partial transaction with all inputs and outputs
|
||||
// fully declared and tries to sign all unsigned inputs that have all
|
||||
|
@ -217,7 +217,8 @@ func (w *mockWalletController) ListLeasedOutputs() (
|
||||
// FundPsbt currently does nothing.
|
||||
func (w *mockWalletController) FundPsbt(*psbt.Packet, int32,
|
||||
chainfee.SatPerKWeight, string, *waddrmgr.KeyScope,
|
||||
base.CoinSelectionStrategy) (int32, error) {
|
||||
base.CoinSelectionStrategy, func(utxo wtxmgr.Credit) bool) (int32,
|
||||
error) {
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user