staticaddr/deposit: reject invalid transitions

Reject nil deposits and final-state deposits before sending FSM
events.

This keeps callers from transitioning stale or completed deposits and
uses the no-lock state helper while deposits are already locked.
This commit is contained in:
Slyghtning 2026-07-01 12:06:50 +02:00
parent 77d9335da2
commit 7f57f6fc6b
No known key found for this signature in database
GPG key ID: F82D456EA023C9BF
2 changed files with 17 additions and 0 deletions

View file

@ -73,6 +73,12 @@ func (d *Deposit) IsInFinalState() bool {
d.Lock()
defer d.Unlock()
return d.isInFinalStateNoLock()
}
// isInFinalStateNoLock returns true if the deposit is final without acquiring
// the deposit lock.
func (d *Deposit) isInFinalStateNoLock() bool {
return d.state == Expired || d.state == Withdrawn ||
d.state == LoopedIn || d.state == HtlcTimeoutSwept ||
d.state == ChannelPublished

View file

@ -520,6 +520,10 @@ func (m *Manager) TransitionDeposits(ctx context.Context, deposits []*Deposit,
outpoints := make([]wire.OutPoint, len(deposits))
for i, d := range deposits {
if d == nil {
return fmt.Errorf("nil deposit at index %d", i)
}
outpoints[i] = d.OutPoint
}
if err := CheckDuplicates(outpoints); err != nil {
@ -536,6 +540,13 @@ func (m *Manager) TransitionDeposits(ctx context.Context, deposits []*Deposit,
lockDeposits(deposits)
defer unlockDeposits(deposits)
for _, deposit := range deposits {
if deposit.isInFinalStateNoLock() {
return fmt.Errorf("deposit %v is no longer active in "+
"state %v", deposit.OutPoint, deposit.state)
}
}
for _, sm := range stateMachines {
err := sm.SendEvent(ctx, event, nil)
if err != nil {