Skip to content

Commit

Permalink
sweep: make sure defaultDeadline is derived from the mature height
Browse files Browse the repository at this point in the history
  • Loading branch information
yyforyongyu committed Jul 15, 2024
1 parent 720d3b2 commit 7183080
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
55 changes: 44 additions & 11 deletions sweep/sweeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ func (s *UtxoSweeper) SweepInput(inp input.Input,
}

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

log.Debugf("Received new block: height=%v, attempt "+
"sweeping %d inputs", epoch.Height, len(inputs))
"sweeping %d inputs:\n%s", epoch.Height,
len(inputs), newLogClosure(func() string {
inps := make(
[]input.Input, 0, len(inputs),
)
for _, in := range inputs {
inps = append(inps, in)
}

return inputTypeSummary(inps)
}))

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

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

// If the input is immature and has a locktime, we'll use the locktime
// height as the starting height.
matured, locktime := pi.isMature(uint32(s.currentHeight))
if !matured {
defaultDeadline = int32(locktime + s.cfg.NoDeadlineConfTarget)
log.Debugf("Input %v is immature, using locktime=%v instead "+
"of current height=%d", pi.OutPoint(), locktime,
s.currentHeight)
}

return defaultDeadline
}

// handleNewInput processes a new input by registering spend notification and
// scheduling sweeping for it.
func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) error {
outpoint := input.input.OutPoint()
pi, pending := s.inputs[outpoint]
if pending {
Expand All @@ -1223,15 +1249,22 @@ func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) error {
Input: input.input,
params: input.params,
rbf: rbfInfo,
// Set the acutal deadline height.
DeadlineHeight: input.params.DeadlineHeight.UnwrapOr(
defaultDeadline,
),
}

// Set the acutal deadline height.
pi.DeadlineHeight = input.params.DeadlineHeight.UnwrapOr(
s.calculateDefaultDeadline(pi),
)

s.inputs[outpoint] = pi
log.Tracef("input %v, state=%v, added to inputs", outpoint, pi.state)

log.Infof("Registered sweep request at block %d: out_point=%v, "+
"witness_type=%v, amount=%v, deadline=%d, params=(%v)",
s.currentHeight, pi.OutPoint(), pi.WitnessType(),
btcutil.Amount(pi.SignDesc().Output.Value), pi.DeadlineHeight,
pi.params)

// Start watching for spend of this input, either by us or the remote
// party.
cancel, err := s.monitorSpend(
Expand Down Expand Up @@ -1629,7 +1662,7 @@ func (s *UtxoSweeper) monitorFeeBumpResult(resultChan <-chan *BumpResult) {
func (s *UtxoSweeper) handleBumpEventTxFailed(r *BumpResult) error {
tx, err := r.Tx, r.Err

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

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

return err
return nil
}

// handleBumpEventTxReplaced handles the case where the sweeping tx has been
Expand Down
2 changes: 1 addition & 1 deletion sweep/sweeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ func TestHandleBumpEventTxFailed(t *testing.T) {

// Call the method under test.
err := s.handleBumpEvent(br)
require.ErrorIs(t, err, errDummy)
require.NoError(t, err)

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

0 comments on commit 7183080

Please sign in to comment.