From 6dc836daa36fec3ccc9496d682083b2a65ab998d Mon Sep 17 00:00:00 2001 From: thomash-acinq <81159533+thomash-acinq@users.noreply.github.com> Date: Thu, 30 Sep 2021 16:10:32 +0200 Subject: [PATCH] Ignore channels without capacity (#1975) Channels with 0 capacity shouldn't exist. But if it happens somehow we should ignore them, not pretend that they are big channels. --- .../scala/fr/acinq/eclair/router/Graph.scala | 20 +++------- .../fr/acinq/eclair/router/GraphSpec.scala | 37 ------------------- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala index c8a330bcc7..85b98f012d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala @@ -17,7 +17,7 @@ package fr.acinq.eclair.router import fr.acinq.bitcoin.Crypto.PublicKey -import fr.acinq.bitcoin.{Btc, ByteVector32, MilliBtc, Satoshi, SatoshiLong} +import fr.acinq.bitcoin.{Btc, ByteVector32, MilliBtc, Satoshi} import fr.acinq.eclair._ import fr.acinq.eclair.payment.relay.Relayer.RelayFees import fr.acinq.eclair.router.Graph.GraphStructure.{DirectedGraph, GraphEdge} @@ -434,13 +434,12 @@ object Graph { def addEdge(edge: GraphEdge): DirectedGraph = { val vertexIn = edge.desc.a val vertexOut = edge.desc.b - val toAdd = edge.copy(capacity = DirectedGraph.getCapacity(edge.capacity, edge.update)) // the graph is allowed to have multiple edges between the same vertices but only one per channel - if (containsEdge(toAdd.desc)) { - removeEdge(toAdd.desc).addEdge(toAdd) // the recursive call will have the original params + if (containsEdge(edge.desc)) { + removeEdge(edge.desc).addEdge(edge) // the recursive call will have the original params } else { val withVertices = addVertex(vertexIn).addVertex(vertexOut) - DirectedGraph(withVertices.vertices.updated(vertexOut, toAdd +: withVertices.vertices(vertexOut))) + DirectedGraph(withVertices.vertices.updated(vertexOut, edge +: withVertices.vertices(vertexOut))) } } @@ -586,7 +585,7 @@ object Graph { } def addDescToMap(desc: ChannelDesc, u: ChannelUpdate, capacity: Satoshi, balance_opt: Option[MilliSatoshi]): Unit = { - mutableMap.put(desc.b, GraphEdge(desc, u, getCapacity(capacity, u), balance_opt) +: mutableMap.getOrElse(desc.b, List.empty[GraphEdge])) + mutableMap.put(desc.b, GraphEdge(desc, u, capacity, balance_opt) +: mutableMap.getOrElse(desc.b, List.empty[GraphEdge])) if (!mutableMap.contains(desc.a)) { mutableMap += desc.a -> List.empty[GraphEdge] } @@ -596,15 +595,6 @@ object Graph { } def graphEdgeToHop(graphEdge: GraphEdge): ChannelHop = ChannelHop(graphEdge.desc.a, graphEdge.desc.b, graphEdge.update) - - /** We need a strictly positive capacity, otherwise path-finding will ignore the edge. */ - def getCapacity(capacity: Satoshi, update: ChannelUpdate): Satoshi = { - if (capacity > 0.sat) { - capacity - } else { - update.htlcMaximumMsat.map(_.truncateToSatoshi + 1.sat).getOrElse(RoutingHeuristics.CAPACITY_CHANNEL_HIGH.truncateToSatoshi) - } - } } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala index 37fafa0fd5..721f24fa6c 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala @@ -113,43 +113,6 @@ class GraphSpec extends AnyFunSuite { assert(graph.edgeSet().size === 6) } - test("add edge without capacity") { - val edgeAB = makeEdge(1L, a, b, 0 msat, 0) - val edgeBC = makeEdge(2L, a, b, 0 msat, 0, capacity = 0 sat, maxHtlc = Some(10010 msat)) - val edgeCD = makeEdge(3L, a, b, 0 msat, 0, capacity = 0 sat, maxHtlc = None) - val channels = SortedMap( - ShortChannelId(1L) -> PublicChannel( - makeChannel(1L, a, b), - ByteVector32.Zeroes, - DEFAULT_CAPACITY, - Some(makeUpdateShort(ShortChannelId(1L), a, b, 1 msat, 10, maxHtlc = Some(10000 msat))), - Some(makeUpdateShort(ShortChannelId(1L), b, a, 1 msat, 10, maxHtlc = Some(10000 msat))), - None), - ShortChannelId(2L) -> PublicChannel( - makeChannel(2L, a, b), - ByteVector32.Zeroes, - 0 sat, - Some(makeUpdateShort(ShortChannelId(2L), a, b, 1 msat, 10, maxHtlc = Some(10010 msat))), - Some(makeUpdateShort(ShortChannelId(2L), b, a, 1 msat, 10, maxHtlc = Some(10010 msat))), - None), - ShortChannelId(3L) -> PublicChannel( - makeChannel(3L, a, b), - ByteVector32.Zeroes, - 0 sat, - Some(makeUpdateShort(ShortChannelId(3L), a, b, 1 msat, 10, maxHtlc = None)), - Some(makeUpdateShort(ShortChannelId(3L), b, a, 1 msat, 10, maxHtlc = None)), - None)) - - { - val graph = DirectedGraph(edgeAB).addEdge(edgeBC).addEdge(edgeCD) - assert(graph.edgesOf(a).map(_.capacity).toSet === Set(11 sat, RoutingHeuristics.CAPACITY_CHANNEL_HIGH.truncateToSatoshi, DEFAULT_CAPACITY)) - } - { - val graph = DirectedGraph.makeGraph(channels) - assert(graph.edgesOf(a).map(_.capacity).toSet === Set(11 sat, RoutingHeuristics.CAPACITY_CHANNEL_HIGH.truncateToSatoshi, DEFAULT_CAPACITY)) - } - } - test("containsEdge should return true if the graph contains that edge, false otherwise") { val graph = DirectedGraph(Seq( makeEdge(1L, a, b, 0 msat, 0),