Skip to content

Commit 0b87965

Browse files
authored
fix: rebuild node service on restart and persist lsp selection
1 parent 9cd942e commit 0b87965

3 files changed

Lines changed: 98 additions & 13 deletions

File tree

LDKNodeMonday/App/WalletClient.swift

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,44 @@ public class WalletClient {
9696
lsp: LightningServiceProvider? = nil
9797
) async {
9898
do {
99+
let targetMode = appMode ?? .live
100+
99101
await MainActor.run {
100102
self.appState = .loading
101-
switch appMode {
103+
switch targetMode {
102104
case .mock:
103105
self.appMode = .mock
104106
self.keyClient = .mock
105107
self.lightningClient = .mock
106-
default:
108+
case .live:
109+
self.appMode = .live
110+
self.keyClient = .live
111+
self.lightningClient = .live
112+
@unknown default:
107113
self.appMode = .live
108114
self.keyClient = .live
109115
self.lightningClient = .live
110116
}
111117
}
112-
try await lightningClient.restart()
118+
119+
switch targetMode {
120+
case .mock:
121+
try LightningNodeService.stopAndReleaseShared()
122+
case .live:
123+
_ = try LightningNodeService.rebuildShared(keyService: self.keyClient)
124+
@unknown default:
125+
_ = try LightningNodeService.rebuildShared(keyService: self.keyClient)
126+
}
127+
128+
try await lightningClient.start()
113129
lightningClient.listenForEvents()
130+
114131
await MainActor.run {
115132
self.network = newNetwork
116133
self.server = newServer
117134
self.appState = .wallet
118135

119-
if let lsp = lsp {
136+
if let lsp {
120137
self.lsp = lsp
121138
}
122139
}

LDKNodeMonday/Service/KeyService/KeyService.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ extension KeyService {
4646
let newBackupInfo = BackupInfo(
4747
mnemonic: currentBackupInfo.mnemonic,
4848
networkString: networkString,
49-
serverURL: currentBackupInfo.serverURL
49+
serverURL: currentBackupInfo.serverURL,
50+
lspString: currentBackupInfo.lspNodeId
5051
)
5152
try self.saveBackupInfo(backupInfo: newBackupInfo)
5253
}
@@ -65,7 +66,8 @@ extension KeyService {
6566
let newBackupInfo = BackupInfo(
6667
mnemonic: currentBackupInfo.mnemonic,
6768
networkString: currentBackupInfo.networkString,
68-
serverURL: url
69+
serverURL: url,
70+
lspString: currentBackupInfo.lspNodeId
6971
)
7072
try self.saveBackupInfo(backupInfo: newBackupInfo)
7173
}

LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class LightningNodeService {
3434
var network: Network
3535
var server: EsploraServer
3636
var lsp: LightningServiceProvider
37+
private var eventListenerTask: Task<Void, Never>?
38+
39+
deinit {
40+
cancelEventListenerTask()
41+
}
3742

3843
init(
3944
keyService: KeyClient = .live
@@ -195,11 +200,59 @@ class LightningNodeService {
195200
}
196201
}
197202

203+
private static func existingInstance() -> LightningNodeService? {
204+
lock.lock()
205+
let instance = _shared
206+
lock.unlock()
207+
return instance
208+
}
209+
210+
static func stopAndReleaseShared() throws {
211+
guard let instance = existingInstance() else { return }
212+
do {
213+
try instance.stop()
214+
} catch let error as NodeError {
215+
if case .NotRunning = error {
216+
instance.cancelEventListenerTask()
217+
} else {
218+
throw error
219+
}
220+
}
221+
stopTrackingSharedInstance()
222+
}
223+
224+
static func rebuildShared(keyService: KeyClient) throws -> LightningNodeService {
225+
if let instance = existingInstance() {
226+
do {
227+
try instance.stop()
228+
} catch let error as NodeError {
229+
if case .NotRunning = error {
230+
instance.cancelEventListenerTask()
231+
} else {
232+
throw error
233+
}
234+
}
235+
}
236+
237+
let service = LightningNodeService(keyService: keyService)
238+
lock.lock()
239+
_shared = service
240+
lock.unlock()
241+
return service
242+
}
243+
244+
private static func stopTrackingSharedInstance() {
245+
lock.lock()
246+
_shared = nil
247+
lock.unlock()
248+
}
249+
198250
func start() async throws {
199251
try ldkNode.start()
200252
}
201253

202254
func stop() throws {
255+
cancelEventListenerTask()
203256
try ldkNode.stop()
204257
}
205258

@@ -211,8 +264,11 @@ class LightningNodeService {
211264
}
212265

213266
func reset() throws {
214-
if LightningNodeService.shared.status().isRunning {
215-
try LightningNodeService.shared.stop()
267+
if let instance = LightningNodeService.existingInstance() {
268+
if instance.status().isRunning {
269+
try instance.stop()
270+
}
271+
instance.cancelEventListenerTask()
216272
}
217273

218274
// Clean up wallet data to prevent conflicts on next initialization
@@ -223,7 +279,7 @@ class LightningNodeService {
223279

224280
try? FileManager.default.removeItem(atPath: networkPath)
225281

226-
LightningNodeService._shared = nil
282+
LightningNodeService.stopTrackingSharedInstance()
227283
}
228284

229285
func nodeId() -> String {
@@ -390,14 +446,17 @@ extension LightningNodeService {
390446

391447
extension LightningNodeService {
392448
func listenForEvents() {
393-
Task {
394-
while true {
395-
let event = await ldkNode.nextEventAsync()
449+
eventListenerTask?.cancel()
450+
eventListenerTask = Task { [weak self] in
451+
guard let self else { return }
452+
while !Task.isCancelled {
453+
let event = await self.ldkNode.nextEventAsync()
454+
if Task.isCancelled { break }
396455
NotificationCenter.default.post(
397456
name: .ldkEventReceived,
398457
object: event
399458
)
400-
try? ldkNode.eventHandled()
459+
try? self.ldkNode.eventHandled()
401460
}
402461
}
403462
}
@@ -407,6 +466,13 @@ extension LightningNodeService {
407466
}
408467
}
409468

469+
extension LightningNodeService {
470+
fileprivate func cancelEventListenerTask() {
471+
eventListenerTask?.cancel()
472+
eventListenerTask = nil
473+
}
474+
}
475+
410476
extension LightningNodeService {
411477
func save(mnemonic: Mnemonic) throws {
412478
let backupInfo = BackupInfo(

0 commit comments

Comments
 (0)