lnwallet: Use TxWeightEstimator for funding transaction.
This commit is contained in:
parent
fb32c3f73d
commit
ced530f98e
@ -504,13 +504,13 @@ func (l *LightningWallet) handleFundingReserveRequest(req *initFundingReserveMsg
|
||||
// don't need to perform any coin selection. Otherwise, attempt to
|
||||
// obtain enough coins to meet the required funding amount.
|
||||
if req.fundingAmount != 0 {
|
||||
// Coin selection is done on the basis of sat-per-byte, so
|
||||
// Coin selection is done on the basis of sat-per-weight, so
|
||||
// we'll query the fee estimator for a fee to use to ensure the
|
||||
// funding transaction gets into the _next_ block.
|
||||
//
|
||||
// TODO(roasbeef): shouldn't be targeting next block
|
||||
satPerByte := l.Cfg.FeeEstimator.EstimateFeePerByte(1)
|
||||
err := l.selectCoinsAndChange(satPerByte, req.fundingAmount,
|
||||
satPerWeight := l.Cfg.FeeEstimator.EstimateFeePerWeight(1)
|
||||
err := l.selectCoinsAndChange(satPerWeight, req.fundingAmount,
|
||||
reservation.ourContribution)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
@ -1039,20 +1039,19 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
|
||||
|
||||
// Next, create the spending scriptSig, and then verify that the script
|
||||
// is complete, allowing us to spend from the funding transaction.
|
||||
theirCommitSig := msg.theirCommitmentSig
|
||||
channelValue := int64(res.partialState.Capacity)
|
||||
hashCache := txscript.NewTxSigHashes(&commitTx)
|
||||
sigHash, err := txscript.CalcWitnessSigHash(witnessScript, hashCache,
|
||||
txscript.SigHashAll, &commitTx, 0, channelValue)
|
||||
if err != nil {
|
||||
msg.err <- fmt.Errorf("counterparty's commitment signature is "+
|
||||
"invalid: %v", err)
|
||||
msg.err <- err
|
||||
msg.completeChan <- nil
|
||||
return
|
||||
}
|
||||
|
||||
// Verify that we've received a valid signature from the remote party
|
||||
// for our version of the commitment transaction.
|
||||
theirCommitSig := msg.theirCommitmentSig
|
||||
sig, err := btcec.ParseSignature(theirCommitSig, btcec.S256())
|
||||
if err != nil {
|
||||
msg.err <- err
|
||||
@ -1268,8 +1267,8 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
// within the passed contribution's inputs. If necessary, a change address will
|
||||
// also be generated.
|
||||
// TODO(roasbeef): remove hardcoded fees and req'd confs for outputs.
|
||||
func (l *LightningWallet) selectCoinsAndChange(feeRate uint64, amt btcutil.Amount,
|
||||
contribution *ChannelContribution) error {
|
||||
func (l *LightningWallet) selectCoinsAndChange(feeRatePerWeight uint64,
|
||||
amt btcutil.Amount, contribution *ChannelContribution) error {
|
||||
|
||||
// We hold the coin select mutex while querying for outputs, and
|
||||
// performing coin selection in order to avoid inadvertent double
|
||||
@ -1277,8 +1276,8 @@ func (l *LightningWallet) selectCoinsAndChange(feeRate uint64, amt btcutil.Amoun
|
||||
l.coinSelectMtx.Lock()
|
||||
defer l.coinSelectMtx.Unlock()
|
||||
|
||||
walletLog.Infof("Performing coin selection using %v sat/byte as fee "+
|
||||
"rate", feeRate)
|
||||
walletLog.Infof("Performing coin selection using %v sat/weight as fee "+
|
||||
"rate", feeRatePerWeight)
|
||||
|
||||
// Find all unlocked unspent witness outputs with greater than 1
|
||||
// confirmation.
|
||||
@ -1291,7 +1290,7 @@ func (l *LightningWallet) selectCoinsAndChange(feeRate uint64, amt btcutil.Amoun
|
||||
// Perform coin selection over our available, unlocked unspent outputs
|
||||
// in order to find enough coins to meet the funding amount
|
||||
// requirements.
|
||||
selectedCoins, changeAmt, err := coinSelect(feeRate, amt, coins)
|
||||
selectedCoins, changeAmt, err := coinSelect(feeRatePerWeight, amt, coins)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1419,33 +1418,9 @@ func selectInputs(amt btcutil.Amount, coins []*Utxo) (btcutil.Amount, []*wire.Ou
|
||||
// change output to fund amt satoshis, adhering to the specified fee rate. The
|
||||
// specified fee rate should be expressed in sat/byte for coin selection to
|
||||
// function properly.
|
||||
func coinSelect(feeRate uint64, amt btcutil.Amount,
|
||||
func coinSelect(feeRatePerWeight uint64, amt btcutil.Amount,
|
||||
coins []*Utxo) ([]*wire.OutPoint, btcutil.Amount, error) {
|
||||
|
||||
const (
|
||||
// txOverhead is the overhead of a transaction residing within
|
||||
// the version number and lock time.
|
||||
txOverhead = 8
|
||||
|
||||
// p2wkhSpendSize an estimate of the number of bytes it takes
|
||||
// to spend a p2wkh output.
|
||||
//
|
||||
// (p2wkh witness) + txid + index + varint script size + sequence
|
||||
// TODO(roasbeef): div by 3 due to witness size?
|
||||
p2wkhSpendSize = (1 + 73 + 1 + 33) + 32 + 4 + 1 + 4
|
||||
|
||||
// p2wkhOutputSize is an estimate of the size of a regualr
|
||||
// p2wkh output.
|
||||
//
|
||||
// 8 (output) + 1 (var int script) + 22 (p2wkh output)
|
||||
p2wkhOutputSize = 8 + 1 + 22
|
||||
|
||||
// p2wkhOutputSize is an estimate of the p2wsh funding uotput.
|
||||
p2wshOutputSize = 8 + 1 + 34
|
||||
)
|
||||
|
||||
var estimatedSize int
|
||||
|
||||
amtNeeded := amt
|
||||
for {
|
||||
// First perform an initial round of coin selection to estimate
|
||||
@ -1455,10 +1430,20 @@ func coinSelect(feeRate uint64, amt btcutil.Amount,
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Based on the selected coins, estimate the size of the final
|
||||
// fully signed transaction.
|
||||
estimatedSize = ((len(selectedUtxos) * p2wkhSpendSize) +
|
||||
p2wshOutputSize + txOverhead)
|
||||
var weightEstimate TxWeightEstimator
|
||||
|
||||
for range selectedUtxos {
|
||||
// Assume all selected inputs are P2WKH inputs.
|
||||
// TODO: Handle wallets that have non-witness UTXOs.
|
||||
weightEstimate.AddP2WKHInput()
|
||||
}
|
||||
|
||||
// Channel funding multisig output is P2WSH.
|
||||
weightEstimate.AddP2WSHOutput()
|
||||
|
||||
// Assume that change output is a P2WKH output.
|
||||
// TODO: Handle wallets that generate non-witness change addresses.
|
||||
weightEstimate.AddP2WKHOutput()
|
||||
|
||||
// The difference between the selected amount and the amount
|
||||
// requested will be used to pay fees, and generate a change
|
||||
@ -1469,9 +1454,10 @@ func coinSelect(feeRate uint64, amt btcutil.Amount,
|
||||
// amount isn't enough to pay fees, then increase the requested
|
||||
// coin amount by the estimate required fee, performing another
|
||||
// round of coin selection.
|
||||
requiredFee := btcutil.Amount(uint64(estimatedSize) * feeRate)
|
||||
requiredFee := btcutil.Amount(
|
||||
uint64(weightEstimate.Weight()) * feeRatePerWeight)
|
||||
if overShootAmt < requiredFee {
|
||||
amtNeeded += requiredFee
|
||||
amtNeeded = amt + requiredFee
|
||||
continue
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user