Skip to content

Commit 7f1b39e

Browse files
committed
Catch exceptions during peer storage deserialization
In some cases, the peer storage we receive could be empty or truncated. We want to be safe and correctly catch every exception possible when deserializing, because we don't want the app to crash and the user to be stuck.
1 parent 6d76f8e commit 7f1b39e

File tree

1 file changed

+11
-8
lines changed
  • modules/core/src/commonMain/kotlin/fr/acinq/lightning/serialization/channel

1 file changed

+11
-8
lines changed

modules/core/src/commonMain/kotlin/fr/acinq/lightning/serialization/channel/Encryption.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,25 @@ object Encryption {
9090
}
9191

9292
private fun fromEncryptedPeerStorageCurrent(key: PrivateKey, encryptedPeerStorage: EncryptedPeerStorage): Result<Serialization.PeerStorageDeserializationResult> {
93-
// data is prefixed by 1 byte of serialization meta-info
94-
return runCatching { decrypt(key.value, encryptedPeerStorage.data.drop(1).toByteArray()) }
95-
.map { Serialization.deserializePeerStorage(encryptedPeerStorage.data[0], it) }
93+
// Data should be prefixed by 1 byte of serialization meta-info, if this is a recent peer storage.
94+
return runCatching {
95+
val decrypted = decrypt(key.value, encryptedPeerStorage.data.drop(1).toByteArray())
96+
Serialization.deserializePeerStorage(encryptedPeerStorage.data[0], decrypted)
97+
}
9698
}
9799

98100
/**
99-
* Backward compatibility for an older backup mechanism where each channel data was stored individually, and restored from channel_reestablish messages.
101+
* Backwards-compatibility for an older backup mechanism where each channel data was stored individually, and restored from channel_reestablish messages.
100102
*/
101103
private fun fromEncryptedPeerStorageLegacyChannelData(key: PrivateKey, encryptedPeerStorage: EncryptedPeerStorage): Result<Serialization.PeerStorageDeserializationResult> {
102-
// The blob is a list of individually encrypted channel data (because each of them was previously stored separately)
104+
// The blob should be a list of individually encrypted channel data (because each of them was previously stored separately).
103105
val input = ByteArrayInput(encryptedPeerStorage.data.toByteArray())
104-
val encryptedChannelDatas = input.readCollection { input.readDelimitedByteArray() }.toList()
105-
val res: List<Result<Serialization.DeserializationResult>> = encryptedChannelDatas.map { data ->
106+
val encryptedChannelDatas = runCatching { input.readCollection { input.readDelimitedByteArray() }.toList() }
107+
.getOrDefault(listOf())
108+
val res = encryptedChannelDatas.map { data ->
106109
runCatching { decrypt(key.value, data.drop(2).toByteArray()) }
107110
.recoverCatching { decrypt(key.value, data) }
108-
.map { Serialization.deserialize(it) }
111+
.mapCatching { Serialization.deserialize(it) }
109112
}
110113

111114
val states = res.mapNotNull { it.getOrNull() }.filterIsInstance<Serialization.DeserializationResult.Success>().map { it.state }

0 commit comments

Comments
 (0)