Merge pull request #2802 from joostjager/probability

routing: probability based path finding
This commit is contained in:
Olaoluwa Osuntokun authored and GitHub committed 2019-06-05 11:30:55 +02:00
commit 7453dbeacc
27 files changed
+1600 -423

No files matched your search

+36 -26
View File
@@ -319,6 +319,13 @@ func (e *EdgeLocator) String() string {
return fmt.Sprintf("%v:%v", e.ChannelID, e.Direction)
}
// edge is a combination of a channel and the node pubkeys of both of its
// endpoints.
type edge struct {
from, to route.Vertex
channel uint64
}
// ChannelRouter is the layer 3 router within the Lightning stack. Below the
// ChannelRouter is the HtlcSwitch, and below that is the Bitcoin blockchain
// itself. The primary role of the ChannelRouter is to respond to queries for
@@ -1598,7 +1605,9 @@ type LightningPayment struct {
// will be returned which describes the path the successful payment traversed
// within the network to reach the destination. Additionally, the payment
// preimage will also be returned.
func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte, *route.Route, error) {
func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte,
*route.Route, error) {
// Before starting the HTLC routing attempt, we'll create a fresh
// payment session which will report our errors back to mission
// control.
@@ -1772,7 +1781,9 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// Always determine chan id ourselves, because a channel
// update with id may not be available.
failedEdge, err := getFailedEdge(rt, route.Vertex(errVertex))
failedEdge, failedAmt, err := getFailedEdge(
rt, route.Vertex(errVertex),
)
if err != nil {
return true
}
@@ -1804,13 +1815,11 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// update to fail?
if !updateOk {
paySession.ReportEdgeFailure(
failedEdge,
failedEdge, 0,
)
}
paySession.ReportEdgePolicyFailure(
route.NewVertex(errSource), failedEdge,
)
paySession.ReportEdgePolicyFailure(failedEdge)
}
switch onionErr := fErr.FailureMessage.(type) {
@@ -1901,7 +1910,7 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// the update and continue.
case *lnwire.FailChannelDisabled:
r.applyChannelUpdate(&onionErr.Update, errSource)
paySession.ReportEdgeFailure(failedEdge)
paySession.ReportEdgeFailure(failedEdge, 0)
return false
// It's likely that the outgoing channel didn't have
@@ -1909,7 +1918,7 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// now, and continue onwards with our path finding.
case *lnwire.FailTemporaryChannelFailure:
r.applyChannelUpdate(onionErr.Update, errSource)
paySession.ReportEdgeFailure(failedEdge)
paySession.ReportEdgeFailure(failedEdge, failedAmt)
return false
// If the send fail due to a node not having the
@@ -1934,7 +1943,7 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// returning errors in order to attempt to black list
// another node.
case *lnwire.FailUnknownNextPeer:
paySession.ReportEdgeFailure(failedEdge)
paySession.ReportEdgeFailure(failedEdge, 0)
return false
// If the node wasn't able to forward for which ever
@@ -1965,14 +1974,12 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// we'll prune the channel in both directions and
// continue with the rest of the routes.
case *lnwire.FailPermanentChannelFailure:
paySession.ReportEdgeFailure(&EdgeLocator{
ChannelID: failedEdge.ChannelID,
Direction: 0,
})
paySession.ReportEdgeFailure(&EdgeLocator{
ChannelID: failedEdge.ChannelID,
Direction: 1,
})
paySession.ReportEdgeFailure(failedEdge, 0)
paySession.ReportEdgeFailure(edge{
from: failedEdge.to,
to: failedEdge.from,
channel: failedEdge.channel,
}, 0)
return false
default:
@@ -1982,12 +1989,14 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession,
// getFailedEdge tries to locate the failing channel given a route and the
// pubkey of the node that sent the error. It will assume that the error is
// associated with the outgoing channel of the error node.
func getFailedEdge(route *route.Route, errSource route.Vertex) (
*EdgeLocator, error) {
// associated with the outgoing channel of the error node. As a second result,
// it returns the amount sent over the edge.
func getFailedEdge(route *route.Route, errSource route.Vertex) (edge,
lnwire.MilliSatoshi, error) {
hopCount := len(route.Hops)
fromNode := route.SourcePubKey
amt := route.TotalAmount
for i, hop := range route.Hops {
toNode := hop.PubKeyBytes
@@ -2006,17 +2015,18 @@ func getFailedEdge(route *route.Route, errSource route.Vertex) (
// If the errSource is the final hop, we assume that the failing
// channel is the incoming channel.
if errSource == fromNode || finalHopFailing {
return newEdgeLocatorByPubkeys(
hop.ChannelID,
&fromNode,
&toNode,
), nil
return edge{
from: fromNode,
to: toNode,
channel: hop.ChannelID,
}, amt, nil
}
fromNode = toNode
amt = hop.AmtToForward
}
return nil, fmt.Errorf("cannot find error source node in route")
return edge{}, 0, fmt.Errorf("cannot find error source node in route")
}
// applyChannelUpdate validates a channel update and if valid, applies it to the