Skip to content

Commit bb8de2a

Browse files
committed
Fix channels sync on migration
1 parent 2fbe604 commit bb8de2a

File tree

3 files changed

+35
-57
lines changed

3 files changed

+35
-57
lines changed

app/src/main/java/to/bitkit/services/MigrationService.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import kotlinx.serialization.json.jsonPrimitive
3131
import kotlinx.serialization.json.put
3232
import to.bitkit.data.SettingsStore
3333
import to.bitkit.data.WidgetsStore
34+
import to.bitkit.data.resetPin
3435
import to.bitkit.data.keychain.Keychain
3536
import to.bitkit.di.json
3637
import to.bitkit.env.Env
@@ -355,13 +356,14 @@ class MigrationService @Inject constructor(
355356
migratePin()
356357

357358
if (hasRNLdkData()) {
358-
migrateLdkData().onFailure { e ->
359-
Logger.warn(
360-
"LDK data migration failed, continuing with other migrations: $e",
361-
e,
362-
context = TAG
363-
)
364-
}
359+
migrateLdkData()
360+
.onFailure { e ->
361+
Logger.warn(
362+
"LDK data migration failed, continuing with other migrations: $e",
363+
e,
364+
context = TAG
365+
)
366+
}
365367
}
366368

367369
if (hasRNMmkvData()) {
@@ -1011,6 +1013,7 @@ class MigrationService @Inject constructor(
10111013
private suspend fun applyRNRemoteSettings(data: ByteArray) {
10121014
runCatching {
10131015
applyRNSettings(decodeBackupData<RNSettings>(data))
1016+
settingsStore.update { it.resetPin() }
10141017
}.onFailure { e ->
10151018
Logger.warn("Failed to decode RN remote settings backup: $e", context = TAG)
10161019
}

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import kotlinx.coroutines.flow.update
4848
import kotlinx.coroutines.launch
4949
import kotlinx.coroutines.withContext
5050
import kotlinx.coroutines.withTimeout
51+
import org.lightningdevkit.ldknode.ChannelDataMigration
5152
import org.lightningdevkit.ldknode.Event
5253
import org.lightningdevkit.ldknode.PaymentId
5354
import org.lightningdevkit.ldknode.SpendableUtxo
@@ -320,11 +321,14 @@ class AppViewModel @Inject constructor(
320321
private suspend fun handleSyncCompleted() {
321322
walletRepo.debounceSyncByEvent()
322323

324+
val isShowingLoading = migrationService.isShowingMigrationLoading.value
325+
val isRestoringRemote = migrationService.isRestoringFromRNRemoteBackup.value
326+
323327
when {
324-
migrationService.isShowingMigrationLoading.value && !isCompletingMigration -> {
328+
isShowingLoading && !isCompletingMigration -> {
325329
completeMigration()
326330
}
327-
migrationService.isRestoringFromRNRemoteBackup.value -> {
331+
isRestoringRemote -> {
328332
completeRNRemoteBackupRestore()
329333
}
330334
}
@@ -338,8 +342,18 @@ class AppViewModel @Inject constructor(
338342
migrationService.setShowingMigrationLoading(false)
339343
}
340344

345+
private fun buildChannelMigrationIfAvailable(): ChannelDataMigration? {
346+
val migration = migrationService.peekPendingChannelMigration() ?: return null
347+
return ChannelDataMigration(
348+
channelManager = migration.channelManager.map { it.toUByte() },
349+
channelMonitors = migration.channelMonitors.map { monitor -> monitor.map { it.toUByte() } },
350+
)
351+
}
352+
341353
private suspend fun completeMigration() {
342-
if (isCompletingMigration) return
354+
if (isCompletingMigration) {
355+
return
356+
}
343357
isCompletingMigration = true
344358

345359
try {
@@ -350,8 +364,14 @@ class AppViewModel @Inject constructor(
350364
}
351365
activityRepo.markAllUnseenActivitiesAsSeen()
352366

353-
lightningRepo.restart()
367+
val channelMigration = buildChannelMigrationIfAvailable()
368+
lightningRepo.stop().onFailure {
369+
Logger.error("Failed to stop node during migration restart", it, context = TAG)
370+
}
371+
delay(500)
372+
lightningRepo.start(channelMigration = channelMigration, shouldRetry = false)
354373
.onSuccess {
374+
migrationService.consumePendingChannelMigration()
355375
walletRepo.syncNodeAndWallet()
356376
.onSuccess {
357377
lightningRepo.getPayments().onSuccess { payments ->

app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,6 @@ class WalletViewModel @Inject constructor(
215215
runCatching {
216216
migrationService.restoreFromRNRemoteBackup()
217217
walletRepo.loadFromCache()
218-
219-
val pendingMigration = migrationService.peekPendingChannelMigration() ?: return@runCatching
220-
val nodeState = lightningState.value.nodeLifecycleState
221-
if (nodeState.isRunningOrStarting()) {
222-
lightningRepo.stop()
223-
delay(NODE_RESTART_DELAY_MS)
224-
startWithChannelMigration(pendingMigration)
225-
}
226218
}.onFailure { e ->
227219
Logger.warn("RN remote backup restore failed, falling back to VSS", e, context = TAG)
228220
backupRepo.performFullRestoreFromLatestBackup(onCacheRestored = walletRepo::loadFromCache)
@@ -253,15 +245,6 @@ class WalletViewModel @Inject constructor(
253245
try {
254246
waitForRestoreIfNeeded()
255247

256-
val hasPendingMigration = migrationService.peekPendingChannelMigration() != null
257-
val nodeState = lightningState.value.nodeLifecycleState
258-
val nodeAlreadyRunning = nodeState.isRunningOrStarting()
259-
260-
if (hasPendingMigration && nodeAlreadyRunning) {
261-
lightningRepo.stop()
262-
delay(NODE_RESTART_DELAY_MS)
263-
}
264-
265248
val channelMigration = buildChannelMigrationIfAvailable()
266249
startNode(walletIndex, channelMigration)
267250
} finally {
@@ -278,7 +261,7 @@ class WalletViewModel @Inject constructor(
278261
}
279262

280263
private fun buildChannelMigrationIfAvailable(): ChannelDataMigration? {
281-
val migration = migrationService.consumePendingChannelMigration() ?: return null
264+
val migration = migrationService.peekPendingChannelMigration() ?: return null
282265
return ChannelDataMigration(
283266
channelManager = migration.channelManager.map { it.toUByte() },
284267
channelMonitors = migration.channelMonitors.map { monitor -> monitor.map { it.toUByte() } },
@@ -305,34 +288,6 @@ class WalletViewModel @Inject constructor(
305288
}
306289
}
307290

308-
private fun startWithChannelMigration(migration: PendingChannelMigration) {
309-
if (!walletExists || isStarting) return
310-
311-
viewModelScope.launch(bgDispatcher) {
312-
isStarting = true
313-
try {
314-
val channelMigration = ChannelDataMigration(
315-
channelManager = migration.channelManager.map { it.toUByte() },
316-
channelMonitors = migration.channelMonitors.map { monitor -> monitor.map { it.toUByte() } },
317-
)
318-
migrationService.consumePendingChannelMigration()
319-
320-
lightningRepo.start(channelMigration = channelMigration)
321-
.onSuccess {
322-
walletRepo.syncBalances()
323-
migrationService.setRestoringFromRNRemoteBackup(true)
324-
}
325-
.onFailure { error ->
326-
Logger.error("Node restart with migration error", error, context = TAG)
327-
if (error !is RecoveryModeException) {
328-
ToastEventBus.send(error)
329-
}
330-
}
331-
} finally {
332-
isStarting = false
333-
}
334-
}
335-
}
336291

337292
fun stop() {
338293
if (!walletExists) return

0 commit comments

Comments
 (0)