Skip to content

Commit 9333ba4

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 184c191 commit 9333ba4

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

sweep/fee_bumper.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,17 @@ 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 once it's
85+
// confirmed.
86+
//
87+
// TODO(yy): Remove the above usage once we remove sweeping non-CPFP
88+
// anchors.
7989
TxFailed
8090

8191
// TxReplaced is sent when the original tx is replaced by a new one.
@@ -269,8 +279,10 @@ func (b *BumpResult) String() string {
269279

270280
// Validate validates the BumpResult so it's safe to use.
271281
func (b *BumpResult) Validate() error {
282+
isFailureEvent := b.Event == TxFailed || b.Event == TxFatal
283+
272284
// Every result must have a tx except the fatal or failed case.
273-
if b.Tx == nil && b.Event != TxFatal {
285+
if b.Tx == nil && !isFailureEvent {
274286
return fmt.Errorf("%w: nil tx", ErrInvalidBumpResult)
275287
}
276288

@@ -285,10 +297,8 @@ func (b *BumpResult) Validate() error {
285297
}
286298

287299
// If it's a failed or fatal event, it must have an error.
288-
if b.Event == TxFatal || b.Event == TxFailed {
289-
if b.Err == nil {
290-
return fmt.Errorf("%w: nil error", ErrInvalidBumpResult)
291-
}
300+
if isFailureEvent && b.Err == nil {
301+
return fmt.Errorf("%w: nil error", ErrInvalidBumpResult)
292302
}
293303

294304
// If it's a confirmed event, it must have a fee rate and fee.

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
@@ -1669,6 +1669,14 @@ func (s *UtxoSweeper) monitorFeeBumpResult(set InputSet,
16691669
// in sweeper and rely solely on this event to mark
16701670
// inputs as Swept?
16711671
if r.Event == TxConfirmed || r.Event == TxFailed {
1672+
// Exit if the tx is failed to be created.
1673+
if r.Tx == nil {
1674+
log.Debugf("Received %v for nil tx, "+
1675+
"exit monitor", r.Event)
1676+
1677+
return
1678+
}
1679+
16721680
log.Debugf("Received %v for sweep tx %v, exit "+
16731681
"fee bump monitor", r.Event,
16741682
r.Tx.TxHash())
@@ -1694,7 +1702,10 @@ func (s *UtxoSweeper) handleBumpEventTxFailed(resp *bumpResp) {
16941702
r := resp.result
16951703
tx, err := r.Tx, r.Err
16961704

1697-
log.Warnf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(), err)
1705+
if tx != nil {
1706+
log.Warnf("Fee bump attempt failed for tx=%v: %v", tx.TxHash(),
1707+
err)
1708+
}
16981709

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

0 commit comments

Comments
 (0)