mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-06 18:54:10 +02:00
routing: convert to node pair based
Previously mission control tracked failures on a per node, per channel basis. This commit changes this to tracking on the level of directed node pairs. The goal of moving to this coarser-grained level is to reduce the number of required payment attempts without compromising payment reliability.
This commit is contained in:
@@ -57,10 +57,10 @@ type RouterBackend struct {
|
||||
|
||||
// MissionControl defines the mission control dependencies of routerrpc.
|
||||
type MissionControl interface {
|
||||
// GetEdgeProbability is expected to return the success probability of a payment
|
||||
// from fromNode along edge.
|
||||
GetEdgeProbability(fromNode route.Vertex,
|
||||
edge routing.EdgeLocator, amt lnwire.MilliSatoshi) float64
|
||||
// GetProbability is expected to return the success probability of a
|
||||
// payment from fromNode to toNode.
|
||||
GetProbability(fromNode, toNode route.Vertex,
|
||||
amt lnwire.MilliSatoshi) float64
|
||||
|
||||
// ResetHistory resets the history of MissionControl returning it to a
|
||||
// state as if no payment attempts have been made.
|
||||
@@ -133,28 +133,50 @@ func (r *RouterBackend) QueryRoutes(ctx context.Context,
|
||||
ignoredNodes[ignoreVertex] = struct{}{}
|
||||
}
|
||||
|
||||
ignoredEdges := make(map[routing.EdgeLocator]struct{})
|
||||
ignoredPairs := make(map[routing.DirectedNodePair]struct{})
|
||||
|
||||
// Convert deprecated ignoredEdges to pairs.
|
||||
for _, ignoredEdge := range in.IgnoredEdges {
|
||||
locator := routing.EdgeLocator{
|
||||
ChannelID: ignoredEdge.ChannelId,
|
||||
pair, err := r.rpcEdgeToPair(ignoredEdge)
|
||||
if err != nil {
|
||||
log.Warnf("Ignore channel %v skipped: %v",
|
||||
ignoredEdge.ChannelId, err)
|
||||
|
||||
continue
|
||||
}
|
||||
if ignoredEdge.DirectionReverse {
|
||||
locator.Direction = 1
|
||||
ignoredPairs[pair] = struct{}{}
|
||||
}
|
||||
|
||||
// Add ignored pairs to set.
|
||||
for _, ignorePair := range in.IgnoredPairs {
|
||||
from, err := route.NewVertexFromBytes(ignorePair.From)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ignoredEdges[locator] = struct{}{}
|
||||
|
||||
to, err := route.NewVertexFromBytes(ignorePair.To)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pair := routing.NewDirectedNodePair(from, to)
|
||||
ignoredPairs[pair] = struct{}{}
|
||||
}
|
||||
|
||||
restrictions := &routing.RestrictParams{
|
||||
FeeLimit: feeLimit,
|
||||
ProbabilitySource: func(node route.Vertex,
|
||||
edge routing.EdgeLocator,
|
||||
ProbabilitySource: func(fromNode, toNode route.Vertex,
|
||||
amt lnwire.MilliSatoshi) float64 {
|
||||
|
||||
if _, ok := ignoredNodes[node]; ok {
|
||||
if _, ok := ignoredNodes[fromNode]; ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
if _, ok := ignoredEdges[edge]; ok {
|
||||
pair := routing.DirectedNodePair{
|
||||
From: fromNode,
|
||||
To: toNode,
|
||||
}
|
||||
if _, ok := ignoredPairs[pair]; ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -162,8 +184,8 @@ func (r *RouterBackend) QueryRoutes(ctx context.Context,
|
||||
return 1
|
||||
}
|
||||
|
||||
return r.MissionControl.GetEdgeProbability(
|
||||
node, edge, amt,
|
||||
return r.MissionControl.GetProbability(
|
||||
fromNode, toNode, amt,
|
||||
)
|
||||
},
|
||||
}
|
||||
@@ -202,6 +224,26 @@ func (r *RouterBackend) QueryRoutes(ctx context.Context,
|
||||
return routeResp, nil
|
||||
}
|
||||
|
||||
// rpcEdgeToPair looks up the provided channel and returns the channel endpoints
|
||||
// as a directed pair.
|
||||
func (r *RouterBackend) rpcEdgeToPair(e *lnrpc.EdgeLocator) (
|
||||
routing.DirectedNodePair, error) {
|
||||
|
||||
a, b, err := r.FetchChannelEndpoints(e.ChannelId)
|
||||
if err != nil {
|
||||
return routing.DirectedNodePair{}, err
|
||||
}
|
||||
|
||||
var pair routing.DirectedNodePair
|
||||
if e.DirectionReverse {
|
||||
pair.From, pair.To = b, a
|
||||
} else {
|
||||
pair.From, pair.To = a, b
|
||||
}
|
||||
|
||||
return pair, nil
|
||||
}
|
||||
|
||||
// calculateFeeLimit returns the fee limit in millisatoshis. If a percentage
|
||||
// based fee limit has been requested, we'll factor in the ratio provided with
|
||||
// the amount of the payment.
|
||||
|
Reference in New Issue
Block a user