From 7343283f9fe90773c6659d0ec35ceecafa6c3b9d Mon Sep 17 00:00:00 2001 From: Bastien Teinturier <31281497+t-bast@users.noreply.github.com> Date: Wed, 6 Jan 2021 18:37:29 +0100 Subject: [PATCH] Add test for duplicate temporary channel id (#1660) This scenario was correctly handled, but we were missing test coverage. --- .../fr/acinq/eclair/channel/Channel.scala | 2 -- .../scala/fr/acinq/eclair/io/PeerSpec.scala | 23 ++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala index ed446d9fc..5952a355d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala @@ -296,7 +296,6 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId context.system.eventStream.publish(ChannelCreated(self, peer, remoteNodeId, isFunder = false, open.temporaryChannelId, open.feeratePerKw, None)) val fundingPubkey = keyManager.fundingPublicKey(localParams.fundingKeyPath).publicKey val channelKeyPath = keyManager.keyPath(localParams, channelVersion) - // TODO: maybe also check uniqueness of temporary channel id val minimumDepth = Helpers.minDepthForFunding(nodeParams, open.fundingSatoshis) val accept = AcceptChannel(temporaryChannelId = open.temporaryChannelId, dustLimitSatoshis = localParams.dustLimit, @@ -346,7 +345,6 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId Helpers.validateParamsFunder(nodeParams, open, accept) match { case Left(t) => handleLocalError(t, d, Some(accept)) case _ => - // TODO: check equality of temporaryChannelId? or should be done upstream val remoteParams = RemoteParams( nodeId = remoteNodeId, dustLimit = accept.dustLimitSatoshis, diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala index 7124dc860..00722920f 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala @@ -21,7 +21,7 @@ import akka.actor.Status.Failure import akka.testkit.{TestFSMRef, TestProbe} import com.google.common.net.HostAndPort import fr.acinq.bitcoin.Crypto.PublicKey -import fr.acinq.bitcoin.{Btc, SatoshiLong, Script} +import fr.acinq.bitcoin.{Block, Btc, SatoshiLong, Script} import fr.acinq.eclair.FeatureSupport.Optional import fr.acinq.eclair.Features.{StaticRemoteKey, Wumbo} import fr.acinq.eclair.TestConstants._ @@ -237,6 +237,27 @@ class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTe monitor.expectMsg(FSM.Transition(reconnectionTask, ReconnectionTask.CONNECTING, ReconnectionTask.IDLE)) } + test("don't spawn a channel with duplicate temporary channel id") { f => + import f._ + + val probe = TestProbe() + system.eventStream.subscribe(probe.ref, classOf[ChannelCreated]) + connect(remoteNodeId, peer, peerConnection) + assert(peer.stateData.channels.isEmpty) + + val open = wire.OpenChannel(Block.RegtestGenesisBlock.hash, randomBytes32, 25000 sat, 0 msat, 483 sat, UInt64(100), 1000 sat, 1 msat, TestConstants.feeratePerKw, CltvExpiryDelta(144), 10, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, 0) + peerConnection.send(peer, open) + awaitCond(peer.stateData.channels.nonEmpty) + assert(probe.expectMsgType[ChannelCreated].temporaryChannelId === open.temporaryChannelId) + peerConnection.expectMsgType[AcceptChannel] + + // open_channel messages with the same temporary channel id should simply be ignored + peerConnection.send(peer, open.copy(fundingSatoshis = 100000 sat, fundingPubkey = randomKey.publicKey)) + probe.expectNoMsg(100 millis) + peerConnection.expectNoMsg(100 millis) + assert(peer.stateData.channels.size === 1) + } + test("don't spawn a wumbo channel if wumbo feature isn't enabled") { f => import f._