mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-29 11:11:53 +01:00
routing: split BuildRoute
Create a couple of subroutines that we can unit test separately.
This commit is contained in:
parent
13399e9e81
commit
aadf385f67
@ -2743,6 +2743,19 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
// amount that this route can carry.
|
||||
useMinAmt := amt == nil
|
||||
|
||||
var runningAmt lnwire.MilliSatoshi
|
||||
if useMinAmt {
|
||||
// For minimum amount routes, aim to deliver at least 1 msat to
|
||||
// the destination. There are nodes in the wild that have a
|
||||
// min_htlc channel policy of zero, which could lead to a zero
|
||||
// amount payment being made.
|
||||
runningAmt = 1
|
||||
} else {
|
||||
// If an amount is specified, we need to build a route that
|
||||
// delivers exactly this amount to the final destination.
|
||||
runningAmt = *amt
|
||||
}
|
||||
|
||||
// We'll attempt to obtain a set of bandwidth hints that helps us select
|
||||
// the best outgoing channel to use in case no outgoing channel is set.
|
||||
bandwidthHints, err := newBandwidthManager(
|
||||
@ -2759,24 +2772,46 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceNode := r.selfNode.PubKeyBytes
|
||||
unifiers, senderAmt, err := getRouteUnifiers(
|
||||
sourceNode, hops, useMinAmt, runningAmt, outgoingChans,
|
||||
r.cachedGraph, bandwidthHints,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pathEdges, receiverAmt, err := getPathEdges(
|
||||
senderAmt, unifiers, bandwidthHints, hops,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build and return the final route.
|
||||
return newRoute(
|
||||
sourceNode, pathEdges, uint32(height),
|
||||
finalHopParams{
|
||||
amt: receiverAmt,
|
||||
totalAmt: receiverAmt,
|
||||
cltvDelta: uint16(finalCltvDelta),
|
||||
records: nil,
|
||||
paymentAddr: payAddr,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// getRouteUnifiers returns a list of edge unifiers for the given route.
|
||||
func getRouteUnifiers(source route.Vertex, hops []route.Vertex,
|
||||
useMinAmt bool, runningAmt lnwire.MilliSatoshi,
|
||||
outgoingChans map[uint64]struct{}, graph routingGraph,
|
||||
bandwidthHints *bandwidthManager) ([]*edgeUnifier, lnwire.MilliSatoshi,
|
||||
error) {
|
||||
|
||||
// Allocate a list that will contain the edge unifiers for this route.
|
||||
unifiers := make([]*edgeUnifier, len(hops))
|
||||
|
||||
var runningAmt lnwire.MilliSatoshi
|
||||
if useMinAmt {
|
||||
// For minimum amount routes, aim to deliver at least 1 msat to
|
||||
// the destination. There are nodes in the wild that have a
|
||||
// min_htlc channel policy of zero, which could lead to a zero
|
||||
// amount payment being made.
|
||||
runningAmt = 1
|
||||
} else {
|
||||
// If an amount is specified, we need to build a route that
|
||||
// delivers exactly this amount to the final destination.
|
||||
runningAmt = *amt
|
||||
}
|
||||
|
||||
// Traverse hops backwards to accumulate fees in the running amounts.
|
||||
source := r.selfNode.PubKeyBytes
|
||||
for i := len(hops) - 1; i >= 0; i-- {
|
||||
toNode := hops[i]
|
||||
|
||||
@ -2793,16 +2828,16 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
// in the graph.
|
||||
u := newNodeEdgeUnifier(source, toNode, outgoingChans)
|
||||
|
||||
err := u.addGraphPolicies(r.cachedGraph)
|
||||
err := u.addGraphPolicies(graph)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Exit if there are no channels.
|
||||
edgeUnifier, ok := u.edgeUnifiers[fromNode]
|
||||
if !ok {
|
||||
log.Errorf("Cannot find policy for node %v", fromNode)
|
||||
return nil, ErrNoChannel{
|
||||
return nil, 0, ErrNoChannel{
|
||||
fromNode: fromNode,
|
||||
position: i,
|
||||
}
|
||||
@ -2822,7 +2857,7 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
log.Errorf("Cannot find policy with amt=%v for node %v",
|
||||
runningAmt, fromNode)
|
||||
|
||||
return nil, ErrNoChannel{
|
||||
return nil, 0, ErrNoChannel{
|
||||
fromNode: fromNode,
|
||||
position: i,
|
||||
}
|
||||
@ -2839,16 +2874,25 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
unifiers[i] = edgeUnifier
|
||||
}
|
||||
|
||||
return unifiers, runningAmt, nil
|
||||
}
|
||||
|
||||
// getPathEdges returns the edges that make up the path and the total amount,
|
||||
// including fees, to send the payment.
|
||||
func getPathEdges(receiverAmt lnwire.MilliSatoshi, unifiers []*edgeUnifier,
|
||||
bandwidthHints *bandwidthManager,
|
||||
hops []route.Vertex) ([]*channeldb.CachedEdgePolicy,
|
||||
lnwire.MilliSatoshi, error) {
|
||||
|
||||
// Now that we arrived at the start of the route and found out the route
|
||||
// total amount, we make a forward pass. Because the amount may have
|
||||
// been increased in the backward pass, fees need to be recalculated and
|
||||
// amount ranges re-checked.
|
||||
var pathEdges []*channeldb.CachedEdgePolicy
|
||||
receiverAmt := runningAmt
|
||||
for i, unifier := range unifiers {
|
||||
edge := unifier.getEdge(receiverAmt, bandwidthHints)
|
||||
if edge == nil {
|
||||
return nil, ErrNoChannel{
|
||||
return nil, 0, ErrNoChannel{
|
||||
fromNode: hops[i-1],
|
||||
position: i,
|
||||
}
|
||||
@ -2864,15 +2908,5 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
pathEdges = append(pathEdges, edge.policy)
|
||||
}
|
||||
|
||||
// Build and return the final route.
|
||||
return newRoute(
|
||||
source, pathEdges, uint32(height),
|
||||
finalHopParams{
|
||||
amt: receiverAmt,
|
||||
totalAmt: receiverAmt,
|
||||
cltvDelta: uint16(finalCltvDelta),
|
||||
records: nil,
|
||||
paymentAddr: payAddr,
|
||||
},
|
||||
)
|
||||
return pathEdges, receiverAmt, nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user