From 025345610e8b5bffdf3d644377082ca536b0f73a Mon Sep 17 00:00:00 2001 From: pm47 Date: Wed, 4 Sep 2019 13:04:20 +0200 Subject: [PATCH] only generate nodes for 100 channels Synchronization of node announcements is currently not optimized (two O(N) operations in `handleNode`), which is why sync tests take a long time. --- .../scala/fr/acinq/eclair/io/PeerSpec.scala | 2 +- .../acinq/eclair/router/RoutingSyncSpec.scala | 54 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) 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 8079ae366d..6ed7d49f1d 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 @@ -44,7 +44,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods { val fakeIPAddress = NodeAddress.fromParts("1.2.3.4", 42000).get val shortChannelIds = RoutingSyncSpec.shortChannelIds.take(100) - val fakeRoutingInfo = shortChannelIds.map(makeFakeRoutingInfo) + val fakeRoutingInfo = shortChannelIds.map(id => makeFakeRoutingInfo(id)) val channels = fakeRoutingInfo.map(_._1.ann).toList val updates = (fakeRoutingInfo.flatMap(_._1.update_1_opt) ++ fakeRoutingInfo.flatMap(_._1.update_2_opt)).toList val nodes = (fakeRoutingInfo.map(_._1.ann.nodeId1) ++ fakeRoutingInfo.map(_._1.ann.nodeId2)).map(RoutingSyncSpec.makeFakeNodeAnnouncement).toList diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala index 2970a958c0..a3879559db 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala @@ -41,12 +41,13 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit import RoutingSyncSpec._ - val fakeRoutingInfo: TreeMap[ShortChannelId, (PublicChannel, NodeAnnouncement, NodeAnnouncement)] = RoutingSyncSpec + val channelsWithNodes = 100 + val fakeRoutingInfo: TreeMap[ShortChannelId, (PublicChannel, Option[NodeAnnouncement], Option[NodeAnnouncement])] = RoutingSyncSpec .shortChannelIds .take(4567) - .foldLeft(TreeMap.empty[ShortChannelId, (PublicChannel, NodeAnnouncement, NodeAnnouncement)]) { - case (m, shortChannelId) => m + (shortChannelId -> makeFakeRoutingInfo(shortChannelId)) - } + .foldLeft((TreeMap.empty[ShortChannelId, (PublicChannel, Option[NodeAnnouncement], Option[NodeAnnouncement])], 0)) { + case ((m, count), shortChannelId) => (m + (shortChannelId -> makeFakeRoutingInfo(shortChannelId, withNodes = (count < channelsWithNodes))), count + 1) + }._1 class YesWatcher extends Actor { override def receive: Receive = { @@ -138,12 +139,12 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit // add some channels and updates to bob and resync fakeRoutingInfo.take(40).values.foreach { - case (pc, na1, na2) => + case (pc, na1_opt, na2_opt) => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.ann)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_1_opt.get)) // we don't send channel_update #2 - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2)) + na1_opt.foreach(na1 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1))) + na2_opt.foreach(na2 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2))) } awaitCond(bob.stateData.channels.size === 40 && countUpdates(bob.stateData.channels) === 40) assert(BasicSyncResult(ranges = 1, queries = 1, channels = 40, updates = 40, nodes = 80) === sync(alice, bob, extendedQueryFlags_opt).counts) @@ -160,15 +161,15 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit // add everything (duplicates will be ignored) fakeRoutingInfo.values.foreach { - case (pc, na1, na2) => + case (pc, na1_opt, na2_opt) => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.ann)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_1_opt.get)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_2_opt.get)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2)) + na1_opt.foreach(na1 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1))) + na2_opt.foreach(na2 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2))) } awaitCond(bob.stateData.channels.size === fakeRoutingInfo.size && countUpdates(bob.stateData.channels) === 2 * fakeRoutingInfo.size, max = 60 seconds) - assert(BasicSyncResult(ranges = 2, queries = 46, channels = fakeRoutingInfo.size, updates = 2 * fakeRoutingInfo.size, nodes = 2 * fakeRoutingInfo.size) === sync(alice, bob, extendedQueryFlags_opt).counts) + assert(BasicSyncResult(ranges = 2, queries = 46, channels = fakeRoutingInfo.size, updates = 2 * fakeRoutingInfo.size, nodes = 2 * channelsWithNodes) === sync(alice, bob, extendedQueryFlags_opt).counts) awaitCond(alice.stateData.channels === bob.stateData.channels, max = 60 seconds) } @@ -186,12 +187,12 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit // add some channels and updates to bob and resync fakeRoutingInfo.take(40).values.foreach { - case (pc, na1, na2) => + case (pc, na1_opt, na2_opt) => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.ann)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_1_opt.get)) // we don't send channel_update #2 - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2)) + na1_opt.foreach(na1 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1))) + na2_opt.foreach(na2 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2))) } awaitCond(bob.stateData.channels.size === 40 && countUpdates(bob.stateData.channels) === 40) assert(BasicSyncResult(ranges = 1, queries = 1, channels = 40, updates = 40, nodes = if (requestNodeAnnouncements) 80 else 0) === sync(alice, bob, extendedQueryFlags_opt).counts) @@ -209,15 +210,15 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit // add everything (duplicates will be ignored) fakeRoutingInfo.values.foreach { - case (pc, na1, na2) => + case (pc, na1_opt, na2_opt) => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.ann)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_1_opt.get)) sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, pc.update_2_opt.get)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1)) - sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2)) + na1_opt.foreach(na1 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na1))) + na2_opt.foreach(na2 => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, na2))) } awaitCond(bob.stateData.channels.size === fakeRoutingInfo.size && countUpdates(bob.stateData.channels) === 2 * fakeRoutingInfo.size, max = 60 seconds) - assert(BasicSyncResult(ranges = 2, queries = 46, channels = fakeRoutingInfo.size - 40, updates = 2 * (fakeRoutingInfo.size - 40), nodes = if (requestNodeAnnouncements) 2 * (fakeRoutingInfo.size - 40) else 0) === sync(alice, bob, extendedQueryFlags_opt).counts) + assert(BasicSyncResult(ranges = 2, queries = 46, channels = fakeRoutingInfo.size - 40, updates = 2 * (fakeRoutingInfo.size - 40), nodes = if (requestNodeAnnouncements) 2 * (channelsWithNodes - 40) else 0) === sync(alice, bob, extendedQueryFlags_opt).counts) awaitCond(alice.stateData.channels === bob.stateData.channels, max = 60 seconds) // bump random channel_updates @@ -228,7 +229,8 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit val bumpedUpdates = (List(0, 42, 147, 153, 654, 834, 4301).map(touchUpdate(_, true)) ++ List(1, 42, 150, 200).map(touchUpdate(_, false))).toSet bumpedUpdates.foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) - assert(BasicSyncResult(ranges = 2, queries = 2, channels = 0, updates = bumpedUpdates.size, nodes = if (requestNodeAnnouncements) 20 else 0) === sync(alice, bob, extendedQueryFlags_opt).counts) + // NB: 6 nodes will be updated because we retrieve updates from 3 channels (0, 1, 42), each of which has 2 nodes + assert(BasicSyncResult(ranges = 2, queries = 2, channels = 0, updates = bumpedUpdates.size, nodes = if (requestNodeAnnouncements) 6 else 0) === sync(alice, bob, extendedQueryFlags_opt).counts) awaitCond(alice.stateData.channels === bob.stateData.channels, max = 60 seconds) if (requestNodeAnnouncements) awaitCond(alice.stateData.nodes === bob.stateData.nodes) } @@ -304,25 +306,23 @@ object RoutingSyncSpec { // this map will store private keys so that we can sign new announcements at will val pub2priv: mutable.Map[PublicKey, PrivateKey] = mutable.HashMap.empty - val unused = randomKey - - def makeFakeRoutingInfo(shortChannelId: ShortChannelId): (PublicChannel, NodeAnnouncement, NodeAnnouncement) = { + def makeFakeRoutingInfo(shortChannelId: ShortChannelId, withNodes: Boolean = true): (PublicChannel, Option[NodeAnnouncement], Option[NodeAnnouncement]) = { val timestamp = Platform.currentTime / 1000 val (priv1, priv2) = { val (priv_a, priv_b) = (randomKey, randomKey) if (Announcements.isNode1(priv_a.publicKey, priv_b.publicKey)) (priv_a, priv_b) else (priv_b, priv_a) } - val priv_funding1 = unused - val priv_funding2 = unused + val priv_funding1 = randomKey + val priv_funding2 = randomKey pub2priv += (priv1.publicKey -> priv1) pub2priv += (priv2.publicKey -> priv2) val channelAnn_12 = channelAnnouncement(shortChannelId, priv1, priv2, priv_funding1, priv_funding2) val channelUpdate_12 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv1, priv2.publicKey, shortChannelId, cltvExpiryDelta = CltvExpiryDelta(7), 0 msat, feeBaseMsat = 766000 msat, feeProportionalMillionths = 10, 500000000L msat, timestamp = timestamp) val channelUpdate_21 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv2, priv1.publicKey, shortChannelId, cltvExpiryDelta = CltvExpiryDelta(7), 0 msat, feeBaseMsat = 766000 msat, feeProportionalMillionths = 10, 500000000L msat, timestamp = timestamp) - val nodeAnnouncement_1 = makeNodeAnnouncement(priv1, "", Color(0, 0, 0), List()) - val nodeAnnouncement_2 = makeNodeAnnouncement(priv2, "", Color(0, 0, 0), List()) + val nodeAnnouncement_1_opt = if (withNodes) Some(makeNodeAnnouncement(priv1, "", Color(0, 0, 0), List())) else None + val nodeAnnouncement_2_opt = if (withNodes) Some(makeNodeAnnouncement(priv2, "", Color(0, 0, 0), List())) else None val publicChannel = PublicChannel(channelAnn_12, ByteVector32.Zeroes, Satoshi(0), Some(channelUpdate_12), Some(channelUpdate_21)) - (publicChannel, nodeAnnouncement_1, nodeAnnouncement_2) + (publicChannel, nodeAnnouncement_1_opt, nodeAnnouncement_2_opt) } def makeNewerChannelUpdate(channelAnnouncement: ChannelAnnouncement, channelUpdate: ChannelUpdate): ChannelUpdate = {