From e7a457f1ce4480fe0fe3781962d67d72632f14db Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Sat, 17 Aug 2019 09:58:36 +0200 Subject: [PATCH] routing: query bandwidth hints before each payment attempt Previously the bandwidth hints were only queried once per payment. This did not allow for concurrent payments changing channel balances. --- routing/payment_session.go | 15 +++++++++++++-- routing/payment_session_source.go | 22 +++++++++------------- routing/payment_session_test.go | 5 +++++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/routing/payment_session.go b/routing/payment_session.go index fe10a501..3894bc60 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -33,7 +33,7 @@ type PaymentSession interface { type paymentSession struct { additionalEdges map[route.Vertex][]*channeldb.ChannelEdgePolicy - bandwidthHints map[uint64]lnwire.MilliSatoshi + getBandwidthHints func() (map[uint64]lnwire.MilliSatoshi, error) sessionSource *SessionSource @@ -97,11 +97,22 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment, CltvLimit: cltvLimit, } + // We'll also obtain a set of bandwidthHints from the lower layer for + // each of our outbound channels. This will allow the path finding to + // skip any links that aren't active or just don't have enough bandwidth + // to carry the payment. New bandwidth hints are queried for every new + // path finding attempt, because concurrent payments may change + // balances. + bandwidthHints, err := p.getBandwidthHints() + if err != nil { + return nil, err + } + path, err := p.pathFinder( &graphParams{ graph: ss.Graph, additionalEdges: p.additionalEdges, - bandwidthHints: p.bandwidthHints, + bandwidthHints: bandwidthHints, }, restrictions, &ss.PathFindingConfig, ss.SelfNode.PubKeyBytes, payment.Target, diff --git a/routing/payment_session_source.go b/routing/payment_session_source.go index 1b8fea5f..b5175cf7 100644 --- a/routing/payment_session_source.go +++ b/routing/payment_session_source.go @@ -97,26 +97,22 @@ func (m *SessionSource) NewPaymentSession(routeHints [][]zpay32.HopHint, } } - // We'll also obtain a set of bandwidthHints from the lower layer for - // each of our outbound channels. This will allow the path finding to - // skip any links that aren't active or just don't have enough - // bandwidth to carry the payment. sourceNode, err := m.Graph.SourceNode() if err != nil { return nil, err } - bandwidthHints, err := generateBandwidthHints( - sourceNode, m.QueryBandwidth, - ) - if err != nil { - return nil, err + + getBandwidthHints := func() (map[uint64]lnwire.MilliSatoshi, + error) { + + return generateBandwidthHints(sourceNode, m.QueryBandwidth) } return &paymentSession{ - additionalEdges: edges, - bandwidthHints: bandwidthHints, - sessionSource: m, - pathFinder: findPath, + additionalEdges: edges, + getBandwidthHints: getBandwidthHints, + sessionSource: m, + pathFinder: findPath, }, nil } diff --git a/routing/payment_session_test.go b/routing/payment_session_test.go index 627f4f85..5d31e902 100644 --- a/routing/payment_session_test.go +++ b/routing/payment_session_test.go @@ -41,6 +41,11 @@ func TestRequestRoute(t *testing.T) { } session := &paymentSession{ + getBandwidthHints: func() (map[uint64]lnwire.MilliSatoshi, + error) { + + return nil, nil + }, sessionSource: sessionSource, pathFinder: findPath, }