Skip to content

Commit f4a7ff8

Browse files
authored
Add chain hash to serialised channel data (#243)
This will prevent users from restoring channels created on a different chain.
1 parent 2ac5cd2 commit f4a7ff8

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/commonMain/kotlin/fr/acinq/eclair/serialization/v1/ChannelState.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,13 @@ data class OnChainFeerates(val mutualCloseFeerate: FeeratePerKw, val claimMainFe
318318
}
319319

320320
@Serializable
321-
data class StaticParams(@Serializable(with = PublicKeyKSerializer::class) val remoteNodeId: PublicKey) {
322-
constructor(from: fr.acinq.eclair.channel.StaticParams) : this(from.remoteNodeId)
321+
data class StaticParams(@Serializable(with = ByteVector32KSerializer::class) val chainHash: ByteVector32, @Serializable(with = PublicKeyKSerializer::class) val remoteNodeId: PublicKey) {
322+
constructor(from: fr.acinq.eclair.channel.StaticParams) : this(from.nodeParams.chainHash, from.remoteNodeId)
323323

324-
fun export(nodeParams: NodeParams) = fr.acinq.eclair.channel.StaticParams(nodeParams, this.remoteNodeId)
324+
fun export(nodeParams: NodeParams): fr.acinq.eclair.channel.StaticParams {
325+
require(chainHash == nodeParams.chainHash) { "restoring data from a different chain" }
326+
return fr.acinq.eclair.channel.StaticParams(nodeParams, this.remoteNodeId)
327+
}
325328
}
326329

327330
@Serializable

src/commonTest/kotlin/fr/acinq/eclair/serialization/StateSerializationTestsCommon.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package fr.acinq.eclair.serialization
22

3+
import fr.acinq.bitcoin.Block
34
import fr.acinq.eclair.Eclair.randomKey
45
import fr.acinq.eclair.channel.TestsHelper
56
import fr.acinq.eclair.tests.utils.EclairTestSuite
67
import kotlinx.serialization.ExperimentalSerializationApi
7-
import kotlin.test.Test
8-
import kotlin.test.assertEquals
8+
import kotlin.test.*
99

1010
@OptIn(ExperimentalSerializationApi::class)
1111
class StateSerializationTestsCommon : EclairTestSuite() {
@@ -34,4 +34,18 @@ class StateSerializationTestsCommon : EclairTestSuite() {
3434
val check1 = Serialization.decrypt(priv, bytes1, bob.staticParams.nodeParams)
3535
assertEquals(bob, check1)
3636
}
37+
38+
@Test
39+
fun `don't restore data from a different chain`() {
40+
val (alice, _) = TestsHelper.reachNormal()
41+
val priv = randomKey()
42+
val bytes = Serialization.encrypt(priv, alice)
43+
val check = Serialization.decrypt(priv, bytes, alice.staticParams.nodeParams)
44+
assertEquals(alice, check)
45+
46+
val error = assertFails {
47+
Serialization.decrypt(priv, bytes, alice.staticParams.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash))
48+
}
49+
assertTrue(error.message!!.contains("restoring data from a different chain"))
50+
}
3751
}

0 commit comments

Comments
 (0)