Skip to content

Commit 9a213eb

Browse files
committed
sweep: make sure nil tx is handled
After previous commit, it should be clear that the tx may be failed to created in a `TxFailed` event. We now make sure to catch it to avoid panic.
1 parent 29c3f66 commit 9a213eb

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

sweep/fee_bumper.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,16 @@ const (
7575
// TxPublished is sent when the broadcast attempt is finished.
7676
TxPublished BumpEvent = iota
7777

78-
// TxFailed is sent when the broadcast attempt fails.
78+
// TxFailed is sent when the tx has encountered a fee-related error
79+
// during its creation or broadcast, or an internal error from the fee
80+
// bumper. In either case the inputs in this tx should be retried with
81+
// either a different grouping strategy or an increased budget.
82+
//
83+
// NOTE: We also send this event when there's a third party spend
84+
// event, and the sweeper will handle cleaning this up.
85+
//
86+
// TODO(yy): Remove the above usage once we remove sweeping non-CPFP
87+
// anchors.
7988
TxFailed
8089

8190
// TxReplaced is sent when the original tx is replaced by a new one.
@@ -270,8 +279,11 @@ func (b *BumpResult) String() string {
270279
// Validate validates the BumpResult so it's safe to use.
271280
func (b *BumpResult) Validate() error {
272281
// Every result must have a tx except the error or fail case.
273-
if b.Tx == nil && b.Event != TxFatal {
274-
return fmt.Errorf("%w: nil tx", ErrInvalidBumpResult)
282+
if b.Tx == nil {
283+
isFail := b.Event == TxFailed || b.Event == TxFatal
284+
if !isFail {
285+
return fmt.Errorf("%w: nil tx", ErrInvalidBumpResult)
286+
}
275287
}
276288

277289
// Every result must have a known event.

sweep/fee_bumper_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,6 @@ func TestBumpResultValidate(t *testing.T) {
9191
}
9292
require.ErrorIs(t, b.Validate(), ErrInvalidBumpResult)
9393

94-
// A failed event without a tx will give an error.
95-
b = BumpResult{
96-
Event: TxFailed,
97-
Err: errDummy,
98-
}
99-
require.ErrorIs(t, b.Validate(), ErrInvalidBumpResult)
100-
10194
// A fatal event without a failure reason will give an error.
10295
b = BumpResult{
10396
Event: TxFailed,
@@ -118,6 +111,13 @@ func TestBumpResultValidate(t *testing.T) {
118111
}
119112
require.NoError(t, b.Validate())
120113

114+
// Tx is allowed to be nil in a TxFailed event.
115+
b = BumpResult{
116+
Event: TxFailed,
117+
Err: errDummy,
118+
}
119+
require.NoError(t, b.Validate())
120+
121121
// Tx is allowed to be nil in a TxFatal event.
122122
b = BumpResult{
123123
Event: TxFatal,

sweep/sweeper.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,14 @@ func (s *UtxoSweeper) monitorFeeBumpResult(set InputSet,
16651665
// in sweeper and rely solely on this event to mark
16661666
// inputs as Swept?
16671667
if r.Event == TxConfirmed || r.Event == TxFailed {
1668+
// Exit if the tx is failed to be created.
1669+
if r.Tx == nil {
1670+
log.Debugf("Received %v for nil tx, "+
1671+
"exit monitor", r.Event)
1672+
1673+
return
1674+
}
1675+
16681676
log.Debugf("Received %v for sweep tx %v, exit "+
16691677
"fee bump monitor", r.Event,
16701678
r.Tx.TxHash())
@@ -1690,7 +1698,10 @@ func (s *UtxoSweeper) handleBumpEventTxFailed(resp *bumpResp) {
16901698
r := resp.result
16911699
tx, err := r.Tx, r.Err
16921700

1693-
log.Warnf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(), err)
1701+
if tx != nil {
1702+
log.Warnf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(),
1703+
err)
1704+
}
16941705

16951706
// NOTE: When marking the inputs as failed, we are using the input set
16961707
// instead of the inputs found in the tx. This is fine for current

0 commit comments

Comments
 (0)