Skip to content

Commit 31c57f4

Browse files
committed
Simplify graph vertex updates and add tests
1 parent 333d102 commit 31c57f4

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

eclair-core/src/main/scala/fr/acinq/eclair/router/Graph.scala

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,15 @@ object Graph {
624624
}
625625
}
626626

627-
case class Vertex(features: Features[NodeFeature], incomingEdges: Map[ChannelDesc, GraphEdge])
627+
case class Vertex(features: Features[NodeFeature], incomingEdges: Map[ChannelDesc, GraphEdge]) {
628+
def update(desc: ChannelDesc, newShortChannelId: RealShortChannelId, newCapacity: Satoshi): Vertex =
629+
incomingEdges.get(desc) match {
630+
case None => this
631+
case Some(edge) =>
632+
val updatedEdge = edge.copy(desc = desc.copy(shortChannelId = newShortChannelId), capacity = newCapacity)
633+
copy(incomingEdges = incomingEdges - desc + (desc.copy(shortChannelId = newShortChannelId) -> updatedEdge))
634+
}
635+
}
628636

629637
/** A graph data structure that uses an adjacency list, stores the incoming edges of the neighbors */
630638
case class DirectedGraph(private val vertices: Map[PublicKey, Vertex]) {
@@ -688,14 +696,10 @@ object Graph {
688696
* @return a new graph with updated vertexes
689697
*/
690698
def updateChannel(desc: ChannelDesc, newShortChannelId: RealShortChannelId, newCapacity: Satoshi): DirectedGraph = {
691-
val newDesc = desc.copy(shortChannelId = newShortChannelId)
692-
val updatedVertices =
693-
vertices
694-
.updatedWith(desc.b)(_.map(vertexB => vertexB.copy(incomingEdges = vertexB.incomingEdges - desc +
695-
(newDesc -> vertexB.incomingEdges(desc).copy(desc = newDesc, capacity = newCapacity)))))
696-
.updatedWith(desc.a)(_.map(vertexA => vertexA.copy(incomingEdges = vertexA.incomingEdges - desc.reversed +
697-
(newDesc.reversed -> vertexA.incomingEdges(desc.reversed).copy(desc = newDesc.reversed, capacity = newCapacity)))))
698-
DirectedGraph(updatedVertices)
699+
DirectedGraph(vertices
700+
.updatedWith(desc.b)(_.map(_.update(desc, newShortChannelId, newCapacity)))
701+
.updatedWith(desc.a)(_.map(_.update(desc.reversed, newShortChannelId, newCapacity)))
702+
)
699703
}
700704

701705
/**

eclair-core/src/test/scala/fr/acinq/eclair/router/BalanceEstimateSpec.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ class BalanceEstimateSpec extends AnyFunSuite {
9898
.couldSend(60_000 msat, TimestampSecond.now())
9999

100100
// a splice-in that increases channel capacity increases high but not low bounds
101-
val balance1 = balance
102-
.updateEdge(a.desc, RealShortChannelId(5), 250 sat)
101+
val balance1 = balance.updateEdge(a.desc, RealShortChannelId(5), 250 sat)
103102
assert(balance1.maxCapacity == 250.sat)
104103
assert(balance1.low == 60_000.msat)
105104
assert(balance1.high == 190_000.msat)

eclair-core/src/test/scala/fr/acinq/eclair/router/GraphSpec.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,25 @@ class GraphSpec extends AnyFunSuite {
461461
assert(MessagePath.dijkstraMessagePath(graph, a, f, Set.empty, boundaries, BlockHeight(793397), wr).isEmpty)
462462
}
463463
}
464+
465+
test("a channel update only changes the scid and capacity of one edge") {
466+
// A --> B has two edges with different short channel ids.
467+
val edge = makeEdge(7, a, b, 1 msat, 1)
468+
val g = makeTestGraph().addEdge(edge)
469+
470+
val g1 = g.updateChannel(ChannelDesc(ShortChannelId(7), a, b), RealShortChannelId(10), 99 sat)
471+
val edge1 = g1.getEdge(ChannelDesc(ShortChannelId(10), a, b)).get
472+
assert(edge1.capacity == 99.sat)
473+
assert(g1.getEdge(ChannelDesc(ShortChannelId(7), a, b)).isEmpty)
474+
475+
// Only the scid and capacity of one edge changes.
476+
assert(g1 == makeTestGraph().addEdge(edge1))
477+
478+
// Updates are symmetric.
479+
assert(g1 == g.updateChannel(ChannelDesc(ShortChannelId(7), b, a), RealShortChannelId(10), 99 sat))
480+
481+
// Updates to an unknown channel do not change the graph.
482+
assert(g == g.updateChannel(ChannelDesc(ShortChannelId(1), randomKey().publicKey, b), RealShortChannelId(10), 99 sat))
483+
}
484+
464485
}

0 commit comments

Comments
 (0)