Skip to content

Commit

Permalink
Ignore channels without capacity (#1975)
Browse files Browse the repository at this point in the history
Channels with 0 capacity shouldn't exist. But if it happens somehow we should ignore them, not pretend that they are big channels.
  • Loading branch information
thomash-acinq authored Sep 30, 2021
1 parent 5fc980c commit 6dc836d
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 52 deletions.
20 changes: 5 additions & 15 deletions eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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)))
}
}

Expand Down Expand Up @@ -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]
}
Expand All @@ -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)
}
}
}

}
Expand Down
37 changes: 0 additions & 37 deletions eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit 6dc836d

Please sign in to comment.