Skip to content

Commit ed8c8a1

Browse files
committed
fix: don't override channel manager and move the check to pre start node
1 parent 362f7d0 commit ed8c8a1

1 file changed

Lines changed: 20 additions & 45 deletions

File tree

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

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ class WalletViewModel @Inject constructor(
6262
companion object {
6363
private const val TAG = "WalletViewModel"
6464
private val TIMEOUT_RESTORE_WAIT = 30.seconds
65-
private const val CHANNEL_RECOVERY_RESTART_DELAY_MS = 500L
6665
}
6766

6867
val lightningState = lightningRepo.lightningState
@@ -267,8 +266,11 @@ class WalletViewModel @Inject constructor(
267266

268267
waitForRestoreIfNeeded()
269268

270-
val channelMigration = buildChannelMigrationIfAvailable()
271-
startNode(walletIndex, channelMigration)
269+
val allMonitorsRetrieved = fetchOrphanedChannelMonitorsIfNeeded()
270+
val channelMigration = buildChannelMigrationIfAvailable(
271+
isOrphanedRecovery = allMonitorsRetrieved != null,
272+
)
273+
startNode(walletIndex, channelMigration, allMonitorsRetrieved)
272274
} finally {
273275
isStarting = false
274276
}
@@ -282,17 +284,19 @@ class WalletViewModel @Inject constructor(
282284
} ?: Logger.warn("waitForRestoreIfNeeded timeout, proceeding anyway", context = TAG)
283285
}
284286

285-
private fun buildChannelMigrationIfAvailable(): ChannelDataMigration? =
287+
private fun buildChannelMigrationIfAvailable(isOrphanedRecovery: Boolean = false): ChannelDataMigration? =
286288
migrationService.peekPendingChannelMigration()?.let { migration ->
287289
ChannelDataMigration(
288-
channelManager = migration.channelManager.map { it.toUByte() },
290+
// don't overwrite channel manager for orphaned recovery, we only need the monitors for the sweep
291+
channelManager = if (isOrphanedRecovery) null else migration.channelManager.map { it.toUByte() },
289292
channelMonitors = migration.channelMonitors.map { monitor -> monitor.map { it.toUByte() } },
290293
)
291294
}
292295

293296
private suspend fun startNode(
294297
walletIndex: Int = 0,
295298
channelMigration: ChannelDataMigration?,
299+
allMonitorsRetrieved: Boolean? = null,
296300
) {
297301
lightningRepo.start(walletIndex, channelMigration = channelMigration)
298302
.onSuccess {
@@ -306,7 +310,9 @@ class WalletViewModel @Inject constructor(
306310
if (_restoreState.value.isIdle()) {
307311
walletRepo.refreshBip21()
308312
}
309-
checkForOrphanedChannelMonitorRecovery()
313+
if (allMonitorsRetrieved == true) {
314+
migrationService.markChannelRecoveryChecked()
315+
}
310316
}
311317
.onFailure {
312318
Logger.error("Node startup error", it, context = TAG)
@@ -328,48 +334,17 @@ class WalletViewModel @Inject constructor(
328334
}
329335
}
330336

331-
private suspend fun checkForOrphanedChannelMonitorRecovery() {
332-
if (migrationService.isChannelRecoveryChecked()) return
333-
334-
Logger.info("Running one-time channel monitor recovery check", context = TAG)
337+
private suspend fun fetchOrphanedChannelMonitorsIfNeeded(): Boolean? {
338+
if (migrationService.isChannelRecoveryChecked()) return null
339+
if (migrationService.peekPendingChannelMigration() != null) return null
335340

336-
val allMonitorsRetrieved = runCatching {
337-
val allRetrieved = migrationService.fetchRNRemoteLdkData()
338-
val channelMigration = buildChannelMigrationIfAvailable()
339-
340-
if (channelMigration == null) {
341-
Logger.info("No channel monitors found on RN backup", context = TAG)
342-
return@runCatching allRetrieved
343-
}
344-
345-
Logger.info(
346-
"Found ${channelMigration.channelMonitors.size} monitors on RN backup, attempting recovery",
347-
context = TAG,
348-
)
349-
350-
lightningRepo.stop().onFailure {
351-
Logger.error("Failed to stop node for channel recovery", it, context = TAG)
352-
}
353-
delay(CHANNEL_RECOVERY_RESTART_DELAY_MS)
354-
lightningRepo.start(channelMigration = channelMigration, shouldRetry = false)
355-
.onSuccess {
356-
migrationService.consumePendingChannelMigration()
357-
walletRepo.syncNodeAndWallet()
358-
walletRepo.syncBalances()
359-
Logger.info("Channel monitor recovery complete", context = TAG)
360-
}
361-
.onFailure {
362-
Logger.error("Failed to restart node after channel recovery", it, context = TAG)
363-
}
341+
Logger.info("Running pre-startup channel monitor recovery check", context = TAG)
364342

365-
allRetrieved
343+
return runCatching {
344+
migrationService.fetchRNRemoteLdkData()
345+
}.onFailure {
346+
Logger.error("Pre-startup channel monitor fetch failed", it, context = TAG)
366347
}.getOrDefault(false)
367-
368-
if (allMonitorsRetrieved) {
369-
migrationService.markChannelRecoveryChecked()
370-
} else {
371-
Logger.warn("Some monitors failed to download, will retry on next startup", context = TAG)
372-
}
373348
}
374349

375350
fun stop() {

0 commit comments

Comments
 (0)