From e2fc3fbecc11684019d232fe5f3e1a795c0c453f Mon Sep 17 00:00:00 2001 From: pm47 Date: Mon, 13 Feb 2017 16:15:32 +0100 Subject: [PATCH] added support for 'initial_routing_sync' feature bit --- .../main/scala/fr/acinq/eclair/Features.scala | 2 ++ .../main/scala/fr/acinq/eclair/Globals.scala | 2 +- .../scala/fr/acinq/eclair/channel/Channel.scala | 8 +++++++- .../scala/fr/acinq/eclair/router/Router.scala | 17 ++++++----------- .../scala/fr/acinq/eclair/FeaturesSpec.scala | 7 +++++++ 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/Features.scala b/eclair-node/src/main/scala/fr/acinq/eclair/Features.scala index 3f7c548b1..ea60f4e60 100644 --- a/eclair-node/src/main/scala/fr/acinq/eclair/Features.scala +++ b/eclair-node/src/main/scala/fr/acinq/eclair/Features.scala @@ -9,4 +9,6 @@ object Features { def isChannelPublic(localFeatures: BinaryData): Boolean = localFeatures.size >= 1 && localFeatures.data(0) == 0x01 + def requiresInitialRoutingSync(localFeatures: BinaryData): Boolean = localFeatures.size >= 2 && localFeatures.data(1) == 0x01 + } diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/Globals.scala b/eclair-node/src/main/scala/fr/acinq/eclair/Globals.scala index 3660c3b5e..95d678cf3 100644 --- a/eclair-node/src/main/scala/fr/acinq/eclair/Globals.scala +++ b/eclair-node/src/main/scala/fr/acinq/eclair/Globals.scala @@ -31,7 +31,7 @@ object Globals { } val global_features = BinaryData("") - val local_features = BinaryData("01") // public channel + val local_features = BinaryData("0101") // public channel val expiry_delta_blocks = config.getInt("expiry-delta-blocks") val htlc_minimum_msat = config.getInt("htlc-minimum-msat") diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/channel/Channel.scala b/eclair-node/src/main/scala/fr/acinq/eclair/channel/Channel.scala index 8d1b3d8be..3f482ae28 100644 --- a/eclair-node/src/main/scala/fr/acinq/eclair/channel/Channel.scala +++ b/eclair-node/src/main/scala/fr/acinq/eclair/channel/Channel.scala @@ -9,7 +9,7 @@ import fr.acinq.eclair.blockchain.peer.CurrentBlockCount import fr.acinq.eclair.channel.Helpers.{Closing, Funding} import fr.acinq.eclair.crypto.{Generators, ShaChain} import fr.acinq.eclair.payment.Binding -import fr.acinq.eclair.router.Announcements +import fr.acinq.eclair.router.{Announcements, SendRoutingState} import fr.acinq.eclair.transactions._ import fr.acinq.eclair.wire._ @@ -82,6 +82,9 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, router: ActorRef, re case Event(Init(remoteGlobalFeatures, remoteLocalFeatures), DATA_WAIT_FOR_INIT(localParams, Left(initFunder), autoSignInterval)) => val temporaryChannelId = Platform.currentTime val firstPerCommitmentPoint = Generators.perCommitPoint(localParams.shaSeed, 0) + if (Features.requiresInitialRoutingSync(remoteLocalFeatures)) { + router ! SendRoutingState(them) + } them ! OpenChannel(temporaryChannelId = temporaryChannelId, fundingSatoshis = initFunder.fundingSatoshis, pushMsat = initFunder.pushMsat, @@ -100,6 +103,9 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, router: ActorRef, re goto(WAIT_FOR_ACCEPT_CHANNEL) using DATA_WAIT_FOR_ACCEPT_CHANNEL(temporaryChannelId, localParams, fundingSatoshis = initFunder.fundingSatoshis, pushMsat = initFunder.pushMsat, remoteGlobalFeatures = remoteGlobalFeatures, remoteLocalFeatures = remoteLocalFeatures, autoSignInterval = autoSignInterval) case Event(Init(remoteGlobalFeatures, remoteLocalFeatures), DATA_WAIT_FOR_INIT(localParams, Right(initFundee), autoSignInterval)) => + if (Features.requiresInitialRoutingSync(remoteLocalFeatures)) { + router ! SendRoutingState(them) + } goto(WAIT_FOR_OPEN_CHANNEL) using DATA_WAIT_FOR_OPEN_CHANNEL(localParams, remoteGlobalFeatures = remoteGlobalFeatures, remoteLocalFeatures = remoteLocalFeatures, autoSignInterval = autoSignInterval) }) diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/router/Router.scala b/eclair-node/src/main/scala/fr/acinq/eclair/router/Router.scala index 567a7ac22..384e6ec35 100644 --- a/eclair-node/src/main/scala/fr/acinq/eclair/router/Router.scala +++ b/eclair-node/src/main/scala/fr/acinq/eclair/router/Router.scala @@ -26,6 +26,7 @@ case class ChannelDesc(id: Long, a: BinaryData, b: BinaryData) case class Hop(nodeId: BinaryData, nextNodeId: BinaryData, lastUpdate: ChannelUpdate) case class RouteRequest(source: BinaryData, target: BinaryData) case class RouteResponse(hops: Seq[Hop]) { require(hops.size > 0, "route cannot be empty") } +case class SendRoutingState(to: ActorRef) // @formatter:on @@ -38,8 +39,6 @@ class Router(watcher: ActorRef) extends Actor with ActorLogging { import Router._ import ExecutionContext.Implicits.global - - context.system.eventStream.subscribe(self, classOf[ChannelChangedState]) context.system.scheduler.schedule(10 seconds, 60 seconds, self, 'tick_broadcast) def receive: Receive = main(nodes = Map(), channels = Map(), updates = Map(), rebroadcast = Nil, awaiting = Set(), stash = Nil) @@ -62,15 +61,11 @@ class Router(watcher: ActorRef) extends Actor with ActorLogging { awaiting: Set[ChannelAnnouncement], stash: Seq[RoutingMessage]): Receive = { - case ChannelChangedState(channel, transport, _, WAIT_FOR_INIT_INTERNAL, _, _) => - // we send all known announcements to the new peer as soon as the connection is opened - log.info(s"info sending all announcements to $channel: channels=${channels.size} nodes=${nodes.size} updates=${updates.size}") - channels.values.foreach(transport ! _) - nodes.values.foreach(transport ! _) - updates.values.foreach(transport ! _) - - case s: ChannelChangedState => - // other channel changed state messages are ignored + case SendRoutingState(remote) => + log.info(s"info sending all announcements to $remote: channels=${channels.size} nodes=${nodes.size} updates=${updates.size}") + channels.values.foreach(remote ! _) + updates.values.foreach(remote ! _) + nodes.values.foreach(remote ! _) case c: ChannelAnnouncement if !Announcements.checkSigs(c) => // TODO: (dirty) this will make the origin channel close the connection diff --git a/eclair-node/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala b/eclair-node/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala index e650ed53e..60855b40b 100644 --- a/eclair-node/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala +++ b/eclair-node/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala @@ -17,4 +17,11 @@ class FeaturesSpec extends FunSuite { assert(isChannelPublic("01") === true) } + test("'initial_routing_sync' feature") { + assert(requiresInitialRoutingSync("") === false) + assert(requiresInitialRoutingSync("01") === false) + assert(requiresInitialRoutingSync("0000") === false) + assert(requiresInitialRoutingSync("0001") === true) + } + }