sweep: add method calculateRetryFeeRate

A minor refactor to prepare the upcoming changes.
This commit is contained in:
yyforyongyu committed 2025-03-26 15:26:11 +08:00
1 parent 861dc145bf
commit 6dbf4ce470
1 file changed
+63 -46
+63 -46
View File
@@ -1267,56 +1267,17 @@ func (t *TxPublisher) createUnknownSpentBumpResult(
SpentInputs: r.spentInputs,
}
// Get the fee function, which will be used to decided the next fee rate
// to use if the sweeper decides to retry sweeping this input.
feeFunc := r.feeFunction
// When the record is failed before the initial broadcast is attempted,
// it will have a nil fee func. In this case, we'll create the fee func
// here.
//
// NOTE: Since the current record is failed and will be deleted, we
// don't need to update the record on this fee function. We only need
// the fee rate data so the sweeper can pick up where we left off.
if feeFunc == nil {
f, err := t.initializeFeeFunction(r.req)
// TODO(yy): The only error we would receive here is when the
// pkScript is not recognized by the weightEstimator. What we
// should do instead is to check the pkScript immediately after
// receiving a sweep request so we don't need to check it again,
// which will also save us from error checking from several
// callsites.
if err != nil {
log.Errorf("Failed to create fee func for record %v: "+
"%v", r.requestID, err)
// Overwrite the event and error so the sweeper will
// remove this input.
result.Event = TxFatal
result.Err = err
return result
}
feeFunc = f
}
// Since the sweeping tx has been replaced by another party's tx, we
// missed this block window to increase its fee rate. To make sure the
// fee rate stays in the initial line, we now ask the fee function to
// give us the next fee rate as if the sweeping tx were RBFed. This new
// fee rate will be used as the starting fee rate if the upper system
// decides to continue sweeping the rest of the inputs.
_, err := feeFunc.Increment()
// Calculate the next fee rate for the retry.
feeRate, err := t.calculateRetryFeeRate(r)
if err != nil {
// The fee function has reached its max position - nothing we
// can do here other than letting the user increase the budget.
log.Errorf("Failed to calculate the next fee rate for "+
"Record(%v): %v", r.requestID, err)
// Overwrite the event and error so the sweeper will
// remove this input.
result.Event = TxFatal
result.Err = err
}
// Attach the new fee rate to be used for the next sweeping attempt.
result.FeeRate = feeFunc.FeeRate()
result.FeeRate = feeRate
return result
}
@@ -1893,3 +1854,59 @@ func (t *TxPublisher) handleReplacementTxError(r *monitorRecord,
return result
}
// calculateRetryFeeRate calculates a new fee rate to be used as the starting
// fee rate for the next sweep attempt if the inputs are to be retried. When the
// fee function is nil it will be created here, and an error is returned if the
// fee func cannot be initialized.
func (t *TxPublisher) calculateRetryFeeRate(
r *monitorRecord) (chainfee.SatPerKWeight, error) {
// Get the fee function, which will be used to decided the next fee rate
// to use if the sweeper decides to retry sweeping this input.
feeFunc := r.feeFunction
// When the record is failed before the initial broadcast is attempted,
// it will have a nil fee func. In this case, we'll create the fee func
// here.
//
// NOTE: Since the current record is failed and will be deleted, we
// don't need to update the record on this fee function. We only need
// the fee rate data so the sweeper can pick up where we left off.
if feeFunc == nil {
f, err := t.initializeFeeFunction(r.req)
// TODO(yy): The only error we would receive here is when the
// pkScript is not recognized by the weightEstimator. What we
// should do instead is to check the pkScript immediately after
// receiving a sweep request so we don't need to check it again,
// which will also save us from error checking from several
// callsites.
if err != nil {
log.Errorf("Failed to create fee func for record %v: "+
"%v", r.requestID, err)
return 0, err
}
feeFunc = f
}
// Since we failed to sweep the inputs, either the sweeping tx has been
// replaced by another party's tx, or the current output values cannot
// cover the budget, we missed this block window to increase its fee
// rate. To make sure the fee rate stays in the initial line, we now ask
// the fee function to give us the next fee rate as if the sweeping tx
// were RBFed. This new fee rate will be used as the starting fee rate
// if the upper system decides to continue sweeping the rest of the
// inputs.
_, err := feeFunc.Increment()
if err != nil {
// The fee function has reached its max position - nothing we
// can do here other than letting the user increase the budget.
log.Errorf("Failed to calculate the next fee rate for "+
"Record(%v): %v", r.requestID, err)
}
return feeFunc.FeeRate(), nil
}