Skip to content

Commit 3158546

Browse files
committed
staticaddr: lock activeDeposits in manager run loop
1 parent a5f1235 commit 3158546

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

looprpc/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module github.com/lightninglabs/loop/looprpc
22

3-
go 1.22.3
3+
go 1.23.0
4+
45
toolchain go1.23.7
56

67
require (

staticaddr/deposit/fsm.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,16 @@ type FSM struct {
141141

142142
blockNtfnChan chan uint32
143143

144+
// quitChan stops after the FSM stops consuming blockNtfnChan.
145+
quitChan chan struct{}
146+
147+
// finalizedDepositChan is used to signal that the deposit has been
148+
// finalized and the FSM can be removed from the manager's memory.
144149
finalizedDepositChan chan wire.OutPoint
150+
151+
// spentChan is used to signal that the FSM should stop processing
152+
// block notifications and exit.
153+
spentChan chan struct{}
145154
}
146155

147156
// NewFSM creates a new state machine that can action on all static address
@@ -167,7 +176,9 @@ func NewFSM(ctx context.Context, deposit *Deposit, cfg *ManagerConfig,
167176
params: params,
168177
address: address,
169178
blockNtfnChan: make(chan uint32),
179+
quitChan: make(chan struct{}),
170180
finalizedDepositChan: finalizedDepositChan,
181+
spentChan: make(chan struct{}),
171182
}
172183

173184
depositStates := depoFsm.DepositStatesV0()
@@ -191,19 +202,22 @@ func NewFSM(ctx context.Context, deposit *Deposit, cfg *ManagerConfig,
191202

192203
depoFsm.ActionEntryFunc = depoFsm.updateDeposit
193204

194-
go func() {
205+
go func(fsm *FSM) {
206+
defer close(fsm.quitChan)
207+
195208
for {
196209
select {
197-
case currentHeight := <-depoFsm.blockNtfnChan:
198-
depoFsm.handleBlockNotification(
199-
ctx, currentHeight,
200-
)
210+
case currentHeight := <-fsm.blockNtfnChan:
211+
fsm.handleBlockNotification(ctx, currentHeight)
212+
213+
case <-fsm.spentChan:
214+
return
201215

202216
case <-ctx.Done():
203217
return
204218
}
205219
}
206-
}()
220+
}(depoFsm)
207221

208222
return depoFsm, nil
209223
}

staticaddr/deposit/manager.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,44 @@ func (m *Manager) Run(ctx context.Context) error {
131131
select {
132132
case height := <-newBlockChan:
133133
// Inform all active deposits about a new block arrival.
134+
m.mu.Lock()
135+
activeDeposits := make([]*FSM, 0, len(m.activeDeposits))
134136
for _, fsm := range m.activeDeposits {
137+
activeDeposits = append(activeDeposits, fsm)
138+
}
139+
m.mu.Unlock()
140+
141+
for _, fsm := range activeDeposits {
135142
select {
136143
case fsm.blockNtfnChan <- uint32(height):
137144

145+
case <-fsm.quitChan:
146+
continue
147+
138148
case <-ctx.Done():
139149
return ctx.Err()
140150
}
141151
}
152+
142153
case outpoint := <-m.finalizedDepositChan:
143-
// If deposits notify us about their finalization, we
144-
// update the manager's internal state and flush the
145-
// finalized deposit from memory.
154+
// If deposits notify us about their finalization,
155+
// flush the finalized deposit from memory and end the
156+
// fsm's block notif goroutine.
157+
m.mu.Lock()
158+
fsm := m.activeDeposits[outpoint]
159+
m.mu.Unlock()
160+
161+
// End the fsm's block notif go routine.
162+
select {
163+
case fsm.spentChan <- struct{}{}:
164+
165+
case <-ctx.Done():
166+
return ctx.Err()
167+
}
168+
169+
m.mu.Lock()
146170
delete(m.activeDeposits, outpoint)
171+
m.mu.Unlock()
147172

148173
case err = <-newBlockErrChan:
149174
return err
@@ -192,7 +217,9 @@ func (m *Manager) recoverDeposits(ctx context.Context) error {
192217
}
193218
}()
194219

220+
m.mu.Lock()
195221
m.activeDeposits[d.OutPoint] = fsm
222+
m.mu.Unlock()
196223
}
197224

198225
return nil

0 commit comments

Comments
 (0)