itest: refactor runBumpFee to fix a flake

Make sure we assertPendingSweepResp in a wait call to wait for the
updated resp.
This commit is contained in:
yyforyongyu
2025-03-20 21:57:19 +08:00
parent eea3561eea
commit 4abc1461ad

View File

@@ -1606,40 +1606,62 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
assertPendingSweepResp := func(broadcastAttempts uint32, budget uint64, assertPendingSweepResp := func(broadcastAttempts uint32, budget uint64,
deadline uint32, startingFeeRate uint64) *wire.MsgTx { deadline uint32, startingFeeRate uint64) *wire.MsgTx {
// Alice should still have one pending sweep. err := wait.NoError(func() error {
pendingSweep := ht.AssertNumPendingSweeps(alice, 1)[0] // Alice should still have one pending sweep.
ps := ht.AssertNumPendingSweeps(alice, 1)[0]
// Validate all fields returned from `PendingSweeps` are as // Validate all fields returned from `PendingSweeps` are
// expected. // as expected.
require.Equal(ht, op.TxidBytes, pendingSweep.Outpoint.TxidBytes) //
require.Equal(ht, op.OutputIndex, // These fields should stay the same during the test so
pendingSweep.Outpoint.OutputIndex) // we assert the values without wait.
require.Equal(ht, walletrpc.WitnessType_TAPROOT_PUB_KEY_SPEND, require.Equal(ht, op.TxidBytes, ps.Outpoint.TxidBytes)
pendingSweep.WitnessType) require.Equal(ht, op.OutputIndex,
require.EqualValuesf(ht, value, pendingSweep.AmountSat, ps.Outpoint.OutputIndex)
"amount not matched: want=%d, got=%d", value, require.Equal(ht,
pendingSweep.AmountSat) walletrpc.WitnessType_TAPROOT_PUB_KEY_SPEND,
require.True(ht, pendingSweep.Immediate) ps.WitnessType)
require.EqualValuesf(ht, value, ps.AmountSat,
"amount not matched: want=%d, got=%d", value,
ps.AmountSat)
require.Equal(ht, broadcastAttempts, // The following fields can change during the test so we
pendingSweep.BroadcastAttempts) // return an error if they don't match, which will be
require.EqualValuesf(ht, budget, pendingSweep.Budget, // checked again in this wait call.
"budget not matched: want=%d, got=%d", budget, if ps.Immediate != true {
pendingSweep.Budget) return fmt.Errorf("Immediate should be true")
}
// Since the request doesn't specify a deadline, we expect the if broadcastAttempts != ps.BroadcastAttempts {
// existing deadline to be used. return fmt.Errorf("broadcastAttempts not "+
require.Equalf(ht, deadline, pendingSweep.DeadlineHeight, "matched: want=%d, got=%d",
"deadline height not matched: want=%d, got=%d", broadcastAttempts, ps.BroadcastAttempts)
deadline, pendingSweep.DeadlineHeight) }
if budget != ps.Budget {
return fmt.Errorf("budget not matched: "+
"want=%d, got=%d", budget, ps.Budget)
}
// Since the request specifies a starting fee rate, we expect // Since the request doesn't specify a deadline, we
// that to be used as the starting fee rate. // expect the existing deadline to be used.
require.Equalf(ht, startingFeeRate, if deadline != ps.DeadlineHeight {
pendingSweep.RequestedSatPerVbyte, "requested "+ return fmt.Errorf("deadline height not "+
"starting fee rate not matched: want=%d, "+ "matched: want=%d, got=%d", deadline,
"got=%d", startingFeeRate, ps.DeadlineHeight)
pendingSweep.RequestedSatPerVbyte) }
// Since the request specifies a starting fee rate, we
// expect that to be used as the starting fee rate.
if startingFeeRate != ps.RequestedSatPerVbyte {
return fmt.Errorf("requested starting fee "+
"rate not matched: want=%d, got=%d",
startingFeeRate,
ps.RequestedSatPerVbyte)
}
return nil
}, wait.DefaultTimeout)
require.NoError(ht, err, "timeout checking pending sweep")
// We expect to see Alice's original tx and her CPFP tx in the // We expect to see Alice's original tx and her CPFP tx in the
// mempool. // mempool.
@@ -1879,7 +1901,7 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
// Finally, we test the behavior of lowering the fee rate. The fee func // Finally, we test the behavior of lowering the fee rate. The fee func
// that has, // that has,
// - starting fee rate: 1 sat/vbyte. // - starting fee rate: 1 sat/vbyte.
// - deadline: 1008. // - deadline: 1.
// - budget: 1000 sats. // - budget: 1000 sats.
bumpFeeReq = &walletrpc.BumpFeeRequest{ bumpFeeReq = &walletrpc.BumpFeeRequest{
Outpoint: op, Outpoint: op,
@@ -1888,22 +1910,45 @@ func runBumpFee(ht *lntest.HarnessTest, alice *node.HarnessNode) {
SatPerVbyte: startFeeRate, SatPerVbyte: startFeeRate,
// The budget and the deadline delta must be set together. // The budget and the deadline delta must be set together.
Budget: smallBudget, Budget: smallBudget,
DeadlineDelta: uint32(sweep.DefaultDeadlineDelta), DeadlineDelta: 1,
} }
alice.RPC.BumpFee(bumpFeeReq) alice.RPC.BumpFee(bumpFeeReq)
// Calculate the ending fee rate, which is used in the above fee bump
// when fee function's max posistion is reached.
txWeight := ht.CalculateTxWeight(sweepTx6)
endingFeeRate := chainfee.NewSatPerKWeight(
btcutil.Amount(smallBudget), txWeight,
)
// Since the fee function has been maxed out, the starting fee rate for
// the next sweep attempt should be the ending fee rate.
//
// TODO(yy): The weight estimator used in the sweeper gives a different
// result than the weight calculated here, which is the result from
// `blockchain.GetTransactionWeight`. For this particular tx:
// - result from the `weightEstimator`: 445 wu
// - result from `GetTransactionWeight`: 444 wu
//
// This means the fee rates are different,
// - `weightEstimator`: 2247 sat/kw, or 8 sat/vb (8.988 round down)
// - here we have 2252 sat/kw, or 9 sat/vb (9.008 round down)
//
// We should investigate and check whether if it's possible to make the
// `weightEstimator` more accurate.
expectedStartFeeRate := uint64(endingFeeRate.FeePerVByte()) - 1
// Assert the pending sweep is created with the expected values: // Assert the pending sweep is created with the expected values:
// - broadcast attempts: 7. // - broadcast attempts: 7.
// - starting fee rate: 1 sat/vbyte. // - starting fee rate: 8 sat/vbyte.
// - deadline: 1008. // - deadline: 1.
// - budget: 1000 sats. // - budget: 1000 sats.
sweepTx7 := assertPendingSweepResp( sweepTx7 := assertPendingSweepResp(
7, smallBudget, deadline, startFeeRate, 7, smallBudget, uint32(currentHeight+1), expectedStartFeeRate,
) )
// Since this budget is too small to cover the RBF, we expect the // Since this budget is too small to cover the RBF, we expect the
// sweeping attempt to fail. // sweeping attempt to fail.
//
require.Equal(ht, sweepTx6.TxHash(), sweepTx7.TxHash(), "tx6 should "+ require.Equal(ht, sweepTx6.TxHash(), sweepTx7.TxHash(), "tx6 should "+
"not be replaced: tx6=%v, tx7=%v", sweepTx6.TxHash(), "not be replaced: tx6=%v, tx7=%v", sweepTx6.TxHash(),
sweepTx7.TxHash()) sweepTx7.TxHash())