lnwallet: Support funding tx fee estimation for more input types.

The fee estimation for funding transactions now properly accounts for
different types of UTXOs spent, whereas previously it assumed all
inputs were spending native P2WKH outputs.
This commit is contained in:
Jim Posen 2017-10-02 20:14:36 -07:00 committed by Olaoluwa Osuntokun
parent 3232fd71c2
commit b29af869c7

@ -1300,12 +1300,13 @@ func (l *LightningWallet) selectCoinsAndChange(feeRatePerWeight uint64,
// double-spending the same set of coins. // double-spending the same set of coins.
contribution.Inputs = make([]*wire.TxIn, len(selectedCoins)) contribution.Inputs = make([]*wire.TxIn, len(selectedCoins))
for i, coin := range selectedCoins { for i, coin := range selectedCoins {
l.lockedOutPoints[*coin] = struct{}{} outpoint := &coin.OutPoint
l.LockOutpoint(*coin) l.lockedOutPoints[*outpoint] = struct{}{}
l.LockOutpoint(*outpoint)
// Empty sig script, we'll actually sign if this reservation is // Empty sig script, we'll actually sign if this reservation is
// queued up to be completed (the other side accepts). // queued up to be completed (the other side accepts).
contribution.Inputs[i] = wire.NewTxIn(coin, nil, nil) contribution.Inputs[i] = wire.NewTxIn(outpoint, nil, nil)
} }
// Record any change output(s) generated as a result of the coin // Record any change output(s) generated as a result of the coin
@ -1383,35 +1384,15 @@ func initStateHints(commit1, commit2 *wire.MsgTx,
// funds, a non-nil error is returned. Additionally, the total amount of the // funds, a non-nil error is returned. Additionally, the total amount of the
// selected coins are returned in order for the caller to properly handle // selected coins are returned in order for the caller to properly handle
// change+fees. // change+fees.
func selectInputs(amt btcutil.Amount, coins []*Utxo) (btcutil.Amount, []*wire.OutPoint, error) { func selectInputs(amt btcutil.Amount, coins []*Utxo) (btcutil.Amount, []*Utxo, error) {
var ( satSelected := btcutil.Amount(0)
selectedUtxos []*wire.OutPoint for i, coin := range coins {
satSelected btcutil.Amount
)
i := 0
for satSelected < amt {
// If we're about to go past the number of available coins,
// then exit with an error.
if i > len(coins)-1 {
return 0, nil, &ErrInsufficientFunds{amt, satSelected}
}
// Otherwise, collect this new coin as it may be used for final
// coin selection.
coin := coins[i]
utxo := &wire.OutPoint{
Hash: coin.Hash,
Index: coin.Index,
}
selectedUtxos = append(selectedUtxos, utxo)
satSelected += coin.Value satSelected += coin.Value
if satSelected >= amt {
i++ return satSelected, coins[:i+1], nil
} }
}
return satSelected, selectedUtxos, nil return 0, nil, &ErrInsufficientFunds{amt, satSelected}
} }
// coinSelect attempts to select a sufficient amount of coins, including a // coinSelect attempts to select a sufficient amount of coins, including a
@ -1419,7 +1400,7 @@ func selectInputs(amt btcutil.Amount, coins []*Utxo) (btcutil.Amount, []*wire.Ou
// specified fee rate should be expressed in sat/byte for coin selection to // specified fee rate should be expressed in sat/byte for coin selection to
// function properly. // function properly.
func coinSelect(feeRatePerWeight uint64, amt btcutil.Amount, func coinSelect(feeRatePerWeight uint64, amt btcutil.Amount,
coins []*Utxo) ([]*wire.OutPoint, btcutil.Amount, error) { coins []*Utxo) ([]*Utxo, btcutil.Amount, error) {
amtNeeded := amt amtNeeded := amt
for { for {
@ -1432,10 +1413,18 @@ func coinSelect(feeRatePerWeight uint64, amt btcutil.Amount,
var weightEstimate TxWeightEstimator var weightEstimate TxWeightEstimator
for range selectedUtxos { for _, utxo := range selectedUtxos {
// Assume all selected inputs are P2WKH inputs. switch utxo.AddressType {
// TODO: Handle wallets that have non-witness UTXOs. case WitnessPubKey:
weightEstimate.AddP2WKHInput() weightEstimate.AddP2WKHInput()
case NestedWitnessPubKey:
weightEstimate.AddNestedP2WKHInput()
case PubKeyHash:
weightEstimate.AddP2PKHInput()
default:
return nil, 0, fmt.Errorf("Unsupported address type: %v",
utxo.AddressType)
}
} }
// Channel funding multisig output is P2WSH. // Channel funding multisig output is P2WSH.