Skip to content

Commit b07e81c

Browse files
committed
fix: add migration peer recovery logic
1 parent 9c242b4 commit b07e81c

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class MigrationService @Inject constructor(
9090
private const val RN_PENDING_METADATA_KEY = "rnPendingMetadata"
9191
private const val RN_PENDING_TRANSFERS_KEY = "rnPendingTransfers"
9292
private const val RN_PENDING_BOOSTS_KEY = "rnPendingBoosts"
93+
private const val RN_DID_ATTEMPT_PEER_RECOVERY_KEY = "rnDidAttemptMigrationPeerRecovery"
9394
private const val OPENING_CURLY_BRACE = "{"
9495
private const val MMKV_ROOT = "persist:root"
9596
private const val RN_WALLET_NAME = "wallet0"
@@ -1251,6 +1252,44 @@ class MigrationService @Inject constructor(
12511252
Logger.info("RN migration completed, marked for post-migration sync", context = TAG)
12521253
}
12531254

1255+
private suspend fun isRnMigrationCompleted(): Boolean {
1256+
val key = stringPreferencesKey(RN_MIGRATION_COMPLETED_KEY)
1257+
return rnMigrationStore.data.first()[key] == "true"
1258+
}
1259+
1260+
private suspend fun didAttemptPeerRecovery(): Boolean {
1261+
val key = stringPreferencesKey(RN_DID_ATTEMPT_PEER_RECOVERY_KEY)
1262+
return rnMigrationStore.data.first()[key] == "true"
1263+
}
1264+
1265+
private suspend fun setDidAttemptPeerRecovery() {
1266+
val key = stringPreferencesKey(RN_DID_ATTEMPT_PEER_RECOVERY_KEY)
1267+
rnMigrationStore.edit { it[key] = "true" }
1268+
}
1269+
1270+
suspend fun tryFetchMigrationPeersFromBackup(): List<String> {
1271+
if (!isRnMigrationCompleted()) return emptyList()
1272+
if (didAttemptPeerRecovery()) return emptyList()
1273+
1274+
setDidAttemptPeerRecovery()
1275+
1276+
return runCatching {
1277+
val data = rnBackupClient.retrieve("peers", fileGroup = "ldk") ?: return emptyList()
1278+
val peers = json.decodeFromString<List<BackupPeerEntry>>(String(data))
1279+
if (peers.isEmpty()) return emptyList()
1280+
1281+
val trustedIds = Env.trustedLnPeers.map { it.nodeId }.toSet()
1282+
val uris = peers
1283+
.filter { it.pubKey !in trustedIds }
1284+
.map { "${it.pubKey}@${it.address}:${it.port}" }
1285+
1286+
Logger.info("Migration peer recovery: fetched ${uris.size} peer(s) from remote backup", context = TAG)
1287+
uris
1288+
}.onFailure {
1289+
Logger.warn("Migration peer recovery failed (will not retry)", it, context = TAG)
1290+
}.getOrDefault(emptyList())
1291+
}
1292+
12541293
suspend fun cleanupAfterMigration() {
12551294
clearPersistedMigrationData()
12561295
setNeedsPostMigrationSync(false)
@@ -2076,6 +2115,13 @@ data class RNWidgetsWithOptions(
20762115
val widgetOptions: Map<String, ByteArray>,
20772116
)
20782117

2118+
@Serializable
2119+
data class BackupPeerEntry(
2120+
val pubKey: String,
2121+
val address: String,
2122+
val port: UShort,
2123+
)
2124+
20792125
private val Context.rnMigrationDataStore: DataStore<Preferences> by preferencesDataStore("rn_migration")
20802126
private val Context.rnKeychainDataStore: DataStore<Preferences> by preferencesDataStore("RN_KEYCHAIN")
20812127

0 commit comments

Comments
 (0)