From 7df1482cfc2316e8707bc99d9b17518945eb6397 Mon Sep 17 00:00:00 2001 From: bitromortac Date: Wed, 15 Mar 2023 16:30:50 +0100 Subject: [PATCH] routing: add capacity to special edges Having a capacity available is important for liquidity estimation. * We add a dummy capacity to hop hints. Hop hints specify neither the capacity nor a maxHTLC size, which is why we assume the channel to have a high capacity relative to the amount we send. * We add a capacity to local edges. These channels should always have a capacity associated with them, even in the neutrino case (a fallback to maxHTLC is not necessary). This is just for completeness, as the probability calculation for local channels is done separately. --- routing/pathfind.go | 16 +++++++++++++++- routing/probability_bimodal.go | 9 ++++++--- routing/unified_edges.go | 5 ++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 3c5397224..e293d320d 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -37,6 +37,11 @@ const ( // to avoid resizing and copies. It should be number on the same order as // the number of active nodes in the network. estimatedNodeCount = 10000 + + // fakeHopHintCapacity is the capacity we assume for hop hint channels. + // This is a high number, which expresses that a hop hint channel should + // be able to route payments. + fakeHopHintCapacity = btcutil.Amount(10 * btcutil.SatoshiPerBitcoin) ) // pathFinder defines the interface of a path finding algorithm. @@ -863,8 +868,17 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, return nil, 0, err } + // We add hop hints that were supplied externally. for _, reverseEdge := range additionalEdgesWithSrc[pivot] { - u.addPolicy(reverseEdge.sourceNode, reverseEdge.edge, 0) + // Hop hints don't contain a capacity. We set one here, + // since a capacity is needed for probability + // calculations. We set a high capacity to act as if + // there is enough liquidity, otherwise the hint would + // not have been added by a wallet. + u.addPolicy( + reverseEdge.sourceNode, reverseEdge.edge, + fakeHopHintCapacity, + ) } amtToSend := partialPath.amountToReceive diff --git a/routing/probability_bimodal.go b/routing/probability_bimodal.go index 3a9beb589..c1718e977 100644 --- a/routing/probability_bimodal.go +++ b/routing/probability_bimodal.go @@ -28,9 +28,12 @@ const ( // the timescale of about a week. DefaultBimodalDecayTime = 7 * 24 * time.Hour - // BimodalScaleMsatLimit is the maximum value for BimodalScaleMsat to - // avoid numerical issues. - BimodalScaleMsatMax = lnwire.MilliSatoshi(21e17) + // BimodalScaleMsatMax is the maximum value for BimodalScaleMsat. We + // limit it here to the fakeHopHintCapacity to avoid issues with hop + // hint probability calculations. + BimodalScaleMsatMax = lnwire.MilliSatoshi( + 1000 * fakeHopHintCapacity / 4, + ) // BimodalEstimatorName is used to identify the bimodal estimator. BimodalEstimatorName = "bimodal" diff --git a/routing/unified_edges.go b/routing/unified_edges.go index 89aaf94ac..e8c2a9270 100644 --- a/routing/unified_edges.go +++ b/routing/unified_edges.go @@ -218,7 +218,10 @@ func (u *edgeUnifier) getEdgeLocal(amt lnwire.MilliSatoshi, maxBandwidth = bandwidth // Update best edge. - bestEdge = &unifiedEdge{policy: edge.policy} + bestEdge = &unifiedEdge{ + policy: edge.policy, + capacity: edge.capacity, + } } return bestEdge