Skip to content

Commit a3e2e69

Browse files
committed
staticaddr: lock deposit reads while withdrawing
1 parent f3854c7 commit a3e2e69

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

staticaddr/withdraw/manager.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ func (m *Manager) recoverWithdrawals(ctx context.Context) error {
294294
return nil
295295
}
296296

297-
// WithdrawDeposits starts a deposits withdrawal flow. If the amount is set to 0
297+
// WithdrawDeposits starts a deposit withdrawal flow. If the amount is set to 0,
298298
// the full amount of the selected deposits will be withdrawn.
299299
func (m *Manager) WithdrawDeposits(ctx context.Context,
300300
outpoints []wire.OutPoint, destAddr string, satPerVbyte int64,
@@ -309,6 +309,16 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
309309
deposits []*deposit.Deposit
310310
allDeposited bool
311311
allWithdrawing bool
312+
lockDeposits = func(deposits []*deposit.Deposit) {
313+
for _, d := range deposits {
314+
d.Lock()
315+
}
316+
}
317+
unlockDeposits = func(deposits []*deposit.Deposit) {
318+
for _, d := range deposits {
319+
d.Unlock()
320+
}
321+
}
312322
)
313323

314324
// Ensure that the deposits are in a state in which they can be
@@ -319,8 +329,8 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
319329

320330
// If not all passed outpoints are in state Deposited, we'll check if
321331
// they are all in state Withdrawing. If they are, then the user is
322-
// requesting a fee bump, if not we'll return an error as we only allow
323-
// fee bumping deposits in state Withdrawing.
332+
// requesting a fee bump, if not, we'll return an error as we only allow
333+
// fee-bumping deposits in state Withdrawing.
324334
if !allDeposited {
325335
deposits, allWithdrawing = m.cfg.DepositManager.AllOutpointsActiveDeposits(
326336
outpoints, deposit.Withdrawing,
@@ -329,7 +339,16 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
329339
if !allWithdrawing {
330340
return "", "", ErrWithdrawingMixedDeposits
331341
}
342+
}
343+
344+
// We lock the deposits for the duration of the withdrawal to avoid
345+
// race conditions.
346+
lockDeposits(deposits)
347+
defer unlockDeposits(deposits)
332348

349+
// Perform some checks on the deposits of a withdrawal if it is a fee
350+
// bump.
351+
if !allDeposited {
333352
// Ensure that all previously withdrawn deposits reference their
334353
// finalized withdrawal tx.
335354
for _, d := range deposits {
@@ -338,7 +357,7 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
338357
}
339358
}
340359

341-
// If republishing of an existing withdrawal is requested we
360+
// If republishing of an existing withdrawal is requested, we
342361
// ensure that all deposits remain clustered in the context of
343362
// the same withdrawal tx. We do this by checking that they have
344363
// the same previous withdrawal tx hash. This ensures that the
@@ -351,7 +370,7 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
351370
}
352371
}
353372

354-
// We also avoid that the user selects a subset of previously
373+
// We also avoid it that the user selects a subset of previously
355374
// clustered deposits for a fee bump. This would result in a
356375
// different transaction shape.
357376
outpointMap := make(map[wire.OutPoint]struct{})
@@ -441,7 +460,7 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
441460
}
442461

443462
// If a previous withdrawal existed across the selected deposits, and
444-
// it isn't the same as the new withdrawal, we remove it from the
463+
// it is different from the new withdrawal, we remove it from the
445464
// finalized withdrawals to stop republishing it on block arrivals.
446465
deposits[0].Lock()
447466
prevTx := deposits[0].FinalizedWithdrawalTx
@@ -454,7 +473,7 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
454473
}
455474

456475
// Attach the finalized withdrawal tx to the deposits. After a client
457-
// restart we can use this address as an indicator to republish the
476+
// restarts, we can use this address as an indicator to republish the
458477
// withdrawal tx and continue the withdrawal.
459478
// Deposits with the same withdrawal tx are part of the same withdrawal.
460479
for _, d := range deposits {
@@ -470,7 +489,7 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
470489
m.mu.Unlock()
471490

472491
// Transition the deposits to the withdrawing state. If the user fee
473-
// bumped a withdrawal this results in a NOOP transition.
492+
// bumped a withdrawal, this results in a NOOP transition.
474493
err = m.cfg.DepositManager.TransitionDeposits(
475494
ctx, deposits, deposit.OnWithdrawInitiated, deposit.Withdrawing,
476495
)

0 commit comments

Comments
 (0)