Skip to content

Commit a0393a0

Browse files
committed
sweep: make sure defaultDeadline is derived from the mature height
1 parent 4dfa759 commit a0393a0

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

sweep/sweeper.go

+44-11
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ func (s *UtxoSweeper) SweepInput(inp input.Input,
525525
}
526526

527527
absoluteTimeLock, _ := inp.RequiredLockTime()
528-
log.Infof("Sweep request received: out_point=%v, witness_type=%v, "+
528+
log.Debugf("Sweep request received: out_point=%v, witness_type=%v, "+
529529
"relative_time_lock=%v, absolute_time_lock=%v, amount=%v, "+
530530
"parent=(%v), params=(%v)", inp.OutPoint(), inp.WitnessType(),
531531
inp.BlocksToMaturity(), absoluteTimeLock,
@@ -725,7 +725,17 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
725725
inputs := s.updateSweeperInputs()
726726

727727
log.Debugf("Received new block: height=%v, attempt "+
728-
"sweeping %d inputs", epoch.Height, len(inputs))
728+
"sweeping %d inputs:\n%s", epoch.Height,
729+
len(inputs), newLogClosure(func() string {
730+
inps := make(
731+
[]input.Input, 0, len(inputs),
732+
)
733+
for _, in := range inputs {
734+
inps = append(inps, in)
735+
}
736+
737+
return inputTypeSummary(inps)
738+
})())
729739

730740
// Attempt to sweep any pending inputs.
731741
s.sweepPendingInputs(inputs)
@@ -1192,13 +1202,29 @@ func (s *UtxoSweeper) mempoolLookup(op wire.OutPoint) fn.Option[wire.MsgTx] {
11921202
return s.cfg.Mempool.LookupInputMempoolSpend(op)
11931203
}
11941204

1195-
// handleNewInput processes a new input by registering spend notification and
1196-
// scheduling sweeping for it.
1197-
func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) error {
1205+
// calculateDefaultDeadline calculates the default deadline height for a sweep
1206+
// request that has no deadline height specified.
1207+
func (s *UtxoSweeper) calculateDefaultDeadline(pi *SweeperInput) int32 {
11981208
// Create a default deadline height, which will be used when there's no
11991209
// DeadlineHeight specified for a given input.
12001210
defaultDeadline := s.currentHeight + int32(s.cfg.NoDeadlineConfTarget)
12011211

1212+
// If the input is immature and has a locktime, we'll use the locktime
1213+
// height as the starting height.
1214+
matured, locktime := pi.isMature(uint32(s.currentHeight))
1215+
if !matured {
1216+
defaultDeadline = int32(locktime + s.cfg.NoDeadlineConfTarget)
1217+
log.Debugf("Input %v is immature, using locktime=%v instead "+
1218+
"of current height=%d", pi.OutPoint(), locktime,
1219+
s.currentHeight)
1220+
}
1221+
1222+
return defaultDeadline
1223+
}
1224+
1225+
// handleNewInput processes a new input by registering spend notification and
1226+
// scheduling sweeping for it.
1227+
func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) error {
12021228
outpoint := input.input.OutPoint()
12031229
pi, pending := s.inputs[outpoint]
12041230
if pending {
@@ -1223,15 +1249,22 @@ func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) error {
12231249
Input: input.input,
12241250
params: input.params,
12251251
rbf: rbfInfo,
1226-
// Set the acutal deadline height.
1227-
DeadlineHeight: input.params.DeadlineHeight.UnwrapOr(
1228-
defaultDeadline,
1229-
),
12301252
}
12311253

1254+
// Set the acutal deadline height.
1255+
pi.DeadlineHeight = input.params.DeadlineHeight.UnwrapOr(
1256+
s.calculateDefaultDeadline(pi),
1257+
)
1258+
12321259
s.inputs[outpoint] = pi
12331260
log.Tracef("input %v, state=%v, added to inputs", outpoint, pi.state)
12341261

1262+
log.Infof("Registered sweep request at block %d: out_point=%v, "+
1263+
"witness_type=%v, amount=%v, deadline=%d, params=(%v)",
1264+
s.currentHeight, pi.OutPoint(), pi.WitnessType(),
1265+
btcutil.Amount(pi.SignDesc().Output.Value), pi.DeadlineHeight,
1266+
pi.params)
1267+
12351268
// Start watching for spend of this input, either by us or the remote
12361269
// party.
12371270
cancel, err := s.monitorSpend(
@@ -1629,7 +1662,7 @@ func (s *UtxoSweeper) monitorFeeBumpResult(resultChan <-chan *BumpResult) {
16291662
func (s *UtxoSweeper) handleBumpEventTxFailed(r *BumpResult) error {
16301663
tx, err := r.Tx, r.Err
16311664

1632-
log.Errorf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(), err)
1665+
log.Warnf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(), err)
16331666

16341667
outpoints := make([]wire.OutPoint, 0, len(tx.TxIn))
16351668
for _, inp := range tx.TxIn {
@@ -1639,7 +1672,7 @@ func (s *UtxoSweeper) handleBumpEventTxFailed(r *BumpResult) error {
16391672
// TODO(yy): should we also remove the failed tx from db?
16401673
s.markInputsPublishFailed(outpoints)
16411674

1642-
return err
1675+
return nil
16431676
}
16441677

16451678
// handleBumpEventTxReplaced handles the case where the sweeping tx has been

sweep/sweeper_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ func TestHandleBumpEventTxFailed(t *testing.T) {
777777

778778
// Call the method under test.
779779
err := s.handleBumpEvent(br)
780-
require.ErrorIs(t, err, errDummy)
780+
require.NoError(t, err)
781781

782782
// Assert the states of the first two inputs are updated.
783783
require.Equal(t, PublishFailed, s.inputs[op1].state)

0 commit comments

Comments
 (0)