diff --git a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt index 687febd9..d0c13b1d 100644 --- a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt +++ b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt @@ -23,29 +23,12 @@ class LdkPersister { val isNew = !file.exists() - if (BackupClient.skipRemoteBackup) { - file.writeBytes(data.write()) - if (isNew) { - LdkEventEmitter.send(EventTypes.new_channel, body) - } - return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed - } - - BackupClient.addToPersistQueue(BackupClient.Label.CHANNEL_MONITOR(channelId=channelId), data.write()) { error -> - if (error != null) { - LdkEventEmitter.send(EventTypes.native_log, "Failed to persist channel (${channelId}) to remote backup: $error") - return@addToPersistQueue - } - - try { - file.writeBytes(data.write()) - } catch (e: Exception) { - //If this fails we can't do much but LDK will retry on startup - LdkEventEmitter.send(EventTypes.native_log, "Failed to locally persist channel (${channelId}) to disk") - return@addToPersistQueue - } + // Always write locally first + val serialized = data.write() + file.writeBytes(serialized) - //Update chain monitor with successful persist + // Update chain monitor on main thread to avoid threading issues + LdkModule.reactContext?.runOnUiThread { val res = LdkModule.chainMonitor?.channel_monitor_updated(channelFundingOutpoint, data._latest_update_id) if (res == null || !res.is_ok) { LdkEventEmitter.send(EventTypes.native_log, "Failed to update chain monitor with persisted channel (${channelId})") @@ -57,7 +40,16 @@ class LdkPersister { } } - return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_InProgress + // Kick off remote backup asynchronously; never block/skip local persist + if (!BackupClient.skipRemoteBackup) { + BackupClient.addToPersistQueue(BackupClient.Label.CHANNEL_MONITOR(channelId=channelId), serialized) { error -> + if (error != null) { + LdkEventEmitter.send(EventTypes.native_log, "Failed to persist channel (${channelId}) to remote backup: $error") + } + } + } + + return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed } catch (e: Exception) { return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_UnrecoverableError } diff --git a/lib/ios/Classes/LdkPersist.swift b/lib/ios/Classes/LdkPersist.swift index 40c0b542..371be000 100644 --- a/lib/ios/Classes/LdkPersist.swift +++ b/lib/ios/Classes/LdkPersist.swift @@ -27,33 +27,17 @@ class LdkPersister: Persist { } let isNew = !FileManager().fileExists(atPath: channelStoragePath.path) - - // If we're not remotely backing up no need to update status later - if BackupClient.skipRemoteBackup { - try Data(data.write()).write(to: channelStoragePath) - if isNew { - LdkEventEmitter.shared.send(withEvent: .new_channel, body: body) - } - return ChannelMonitorUpdateStatus.Completed - } - - BackupClient.addToPersistQueue(.channelMonitor(id: channelIdHex), data.write()) { error in - if let error { - LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed persist channel on remote server (\(channelIdHex)). \(error.localizedDescription)") - return - } - - // Callback for when the persist queue queue entry is processed - do { - try Data(data.write()).write(to: channelStoragePath) - } catch { - // If this fails we can't do much but LDK will retry on startup - LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed to locally persist channel (\(channelIdHex)). \(error.localizedDescription)") - return - } - - // Update chainmonitor with successful persist - let res = Ldk.chainMonitor?.channelMonitorUpdated(fundingTxo: channelFundingOutpoint, completedUpdateId: data.getLatestUpdateId()) + + // Always write locally first + let serialized = Data(data.write()) + try serialized.write(to: channelStoragePath) + + // Notify chain monitor on main thread to avoid threading issues + DispatchQueue.main.async { + let res = Ldk.chainMonitor?.channelMonitorUpdated( + fundingTxo: channelFundingOutpoint, + completedUpdateId: data.getLatestUpdateId() + ) if let error = res?.getError() { LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed to update chain monitor for channel (\(channelIdHex)) Error \(error.getValueType()).") } else { @@ -63,10 +47,19 @@ class LdkPersister: Persist { } } } - - return ChannelMonitorUpdateStatus.InProgress + + // Kick off remote backup asynchronously; log but never block/skip local persist + if !BackupClient.skipRemoteBackup { + BackupClient.addToPersistQueue(.channelMonitor(id: channelIdHex), [UInt8](serialized)) { error in + if let error { + LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed persist channel on remote server (\(channelIdHex)). \(error.localizedDescription)") + } + } + } + + return ChannelMonitorUpdateStatus.Completed } catch { - LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed to persist channel (\(channelIdHex)) to disk Error \(error.localizedDescription).") + LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error. Failed to locally persist channel (\(channelIdHex)). \(error.localizedDescription)") return ChannelMonitorUpdateStatus.UnrecoverableError } } diff --git a/lib/package.json b/lib/package.json index fed8f707..8bf4b949 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,7 +1,7 @@ { "name": "@synonymdev/react-native-ldk", "title": "React Native LDK", - "version": "0.0.160", + "version": "0.0.161", "description": "React Native wrapper for LDK", "main": "./dist/index.js", "types": "./dist/index.d.ts",