Skip to content

Commit ef88cb0

Browse files
committed
Add comment in get_route describing our dijkstra's mods
1 parent 1e2f06c commit ef88cb0

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

lightning/src/routing/router.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,42 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
362362
// 8. Choose the best route by the lowest total fee.
363363

364364
// As for the actual search algorithm,
365-
// we do a payee-to-payer Dijkstra's sorting by each node's distance from the payee
366-
// plus the minimum per-HTLC fee to get from it to another node (aka "shitty A*").
365+
// we do a payee-to-payer pseudo-Dijkstra's sorting by each node's distance from the payee
366+
// plus the minimum per-HTLC fee to get from it to another node (aka "shitty pseudo-A*").
367+
//
368+
// We are not a faithful Dijkstra's implementation because we can change values which impact
369+
// earlier nodes while processing later nodes. Specifically, if we reach a channel with a lower
370+
// liquidity limit (via htlc_maximum_msat, on-chain capacity or assumed liquidity limits) then
371+
// the value we are currently attempting to send over a path, we simply reduce the value being
372+
// sent along the path for any hops after that channel. This may imply that later fees (which
373+
// we've already tabulated) are lower because a smaller value is passing through the channels
374+
// (and the proportional fee is thus lower). There isn't a trivial way to recalculate the
375+
// channels which were selected earlier (and which may still be used for other paths without a
376+
// lower liquidity limit), so we simply accept that some liquidity-limited paths may be
377+
// de-preferenced.
378+
//
379+
// One potentially problematic case for this algorithm would be if there are many
380+
// liquidity-limited paths which are liquidity-limited near the destination (ie early in our
381+
// graph walking), we may never find a liquidity-unlimited path which has lower proportional
382+
// fee (and only lower abslute fee when considering the ultimate value sent). Because we only
383+
// consider paths with at least 5% of the total value being sent, the damage from such a case
384+
// should be limited, however this could be further reduced in the future by calculating fees
385+
// on the amount we wish to route over a path, not the amount we are routing over a path.
386+
//
387+
// Alternatively, we could store more detailed path information in the heap (targets, below)
388+
// and index the best-path map (dist, below) by node *and* HTLC limits, however that would blow
389+
// up the runtime significantly both algorithmically (as we'd traverse nodes multiple times)
390+
// and practically (as we would need to store dynamically-allocated path information in heap
391+
// objects, increasing malloc traffic and indirect memory access significantly). Further, the
392+
// results of such an algorithm would likely be biased towards lower-value paths.
393+
//
394+
// Further, we could return to a faithful Dijkstra's algorithm by rejecting paths with limits
395+
// outside of our current search value, running a path search more times to gather candidate
396+
// paths at different values. While this may be acceptable, further path searches may increase
397+
// runtime for little gain. Specifically, the current algorithm rather efficiently explores the
398+
// graph for candidate paths, calculating the maximum value which can realistically be sent at
399+
// the same time, remaining generic across different payment values.
400+
//
367401
// TODO: There are a few tweaks we could do, including possibly pre-calculating more stuff
368402
// to use as the A* heuristic beyond just the cost to get one node further than the current
369403
// one.

0 commit comments

Comments
 (0)