sweep: make sweeper aware of unconfirmed parent transactions.

Extend the fee estimator to take into account parent transactions with
their weights and fees.

Do not try to cpfp parent transactions that have a higher fee rate than
the sweep tx fee rate.
This commit is contained in:
Joost Jager
2020-09-04 11:28:17 +02:00
parent 3e3d8487fb
commit 681496b474
13 changed files with 334 additions and 30 deletions

View File

@@ -134,9 +134,9 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte,
currentBlockHeight uint32, feePerKw chainfee.SatPerKWeight,
signer input.Signer) (*wire.MsgTx, error) {
inputs, txWeight := getWeightEstimate(inputs)
inputs, estimator := getWeightEstimate(inputs, feePerKw)
txFee := feePerKw.FeeForWeight(txWeight)
txFee := estimator.fee()
// Sum up the total value contained in the inputs.
var totalSum btcutil.Amount
@@ -208,21 +208,29 @@ func createSweepTx(inputs []input.Input, outputPkScript []byte,
}
log.Infof("Creating sweep transaction %v for %v inputs (%s) "+
"using %v sat/kw, tx_fee=%v", sweepTx.TxHash(), len(inputs),
inputTypeSummary(inputs), int64(feePerKw), txFee)
"using %v sat/kw, tx_weight=%v, tx_fee=%v, parents_count=%v, "+
"parents_fee=%v, parents_weight=%v",
sweepTx.TxHash(), len(inputs),
inputTypeSummary(inputs), int64(feePerKw),
estimator.weight(), txFee,
len(estimator.parents), estimator.parentsFee,
estimator.parentsWeight,
)
return sweepTx, nil
}
// getWeightEstimate returns a weight estimate for the given inputs.
// Additionally, it returns counts for the number of csv and cltv inputs.
func getWeightEstimate(inputs []input.Input) ([]input.Input, int64) {
func getWeightEstimate(inputs []input.Input, feeRate chainfee.SatPerKWeight) (
[]input.Input, *weightEstimator) {
// We initialize a weight estimator so we can accurately asses the
// amount of fees we need to pay for this sweep transaction.
//
// TODO(roasbeef): can be more intelligent about buffering outputs to
// be more efficient on-chain.
weightEstimate := newWeightEstimator()
weightEstimate := newWeightEstimator(feeRate)
// Our sweep transaction will pay to a single segwit p2wkh address,
// ensure it contributes to our weight estimate.
@@ -247,7 +255,7 @@ func getWeightEstimate(inputs []input.Input) ([]input.Input, int64) {
sweepInputs = append(sweepInputs, inp)
}
return sweepInputs, int64(weightEstimate.weight())
return sweepInputs, weightEstimate
}
// inputSummary returns a string containing a human readable summary about the