lnrpc+routing: Only accept a single route for SendToRoute

This commit is contained in:
Joost Jager committed 2019-05-15 11:54:46 +02:00
1 parent 0b66d56aab
commit ba3fa94268
10 files changed
+693 -736

No files matched your search

+4 -8
View File
@@ -231,18 +231,14 @@ func (m *missionControl) NewPaymentSession(routeHints [][]zpay32.HopHint,
}, nil
}
// NewPaymentSessionFromRoutes creates a new paymentSession instance that will
// skip all path finding, and will instead utilize a set of pre-built routes.
// This constructor allows callers to specify their own routes which can be
// used for things like channel rebalancing, and swaps.
func (m *missionControl) NewPaymentSessionFromRoutes(routes []*route.Route) *paymentSession {
// NewPaymentSessionForRoute creates a new paymentSession instance that is just
// used for failure reporting to missioncontrol.
func (m *missionControl) NewPaymentSessionForRoute(preBuiltRoute *route.Route) *paymentSession {
return &paymentSession{
pruneViewSnapshot: m.GraphPruneView(),
haveRoutes: true,
preBuiltRoutes: routes,
errFailedPolicyChans: make(map[EdgeLocator]struct{}),
mc: m,
pathFinder: findPath,
preBuiltRoute: preBuiltRoute,
}
}
+11 -13
View File
@@ -32,8 +32,8 @@ type paymentSession struct {
mc *missionControl
haveRoutes bool
preBuiltRoutes []*route.Route
preBuiltRoute *route.Route
preBuiltRouteTried bool
pathFinder pathFinder
}
@@ -115,19 +115,17 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment,
height uint32, finalCltvDelta uint16) (*route.Route, error) {
switch {
// If we have a set of pre-built routes, then we'll just pop off the
// next route from the queue, and use it directly.
case p.haveRoutes && len(p.preBuiltRoutes) > 0:
nextRoute := p.preBuiltRoutes[0]
p.preBuiltRoutes[0] = nil // Set to nil to avoid GC leak.
p.preBuiltRoutes = p.preBuiltRoutes[1:]
return nextRoute, nil
// If we have a pre-built route, use that directly.
case p.preBuiltRoute != nil && !p.preBuiltRouteTried:
p.preBuiltRouteTried = true
// If we were instantiated with a set of pre-built routes, and we've
// run out, then we'll return a terminal error.
case p.haveRoutes && len(p.preBuiltRoutes) == 0:
return nil, fmt.Errorf("pre-built routes exhausted")
return p.preBuiltRoute, nil
// If the pre-built route has been tried already, the payment session is
// over.
case p.preBuiltRoute != nil:
return nil, fmt.Errorf("pre-built route already tried")
}
// Otherwise we actually need to perform path finding, so we'll obtain
+17 -13
View File
@@ -20,6 +20,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/multimutex"
@@ -1523,21 +1524,24 @@ func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte, *route
return r.sendPayment(payment, paySession)
}
// SendToRoute attempts to send a payment as described within the passed
// LightningPayment through the provided routes. This function is blocking
// and will return either: when the payment is successful, or all routes
// have been attempted and resulted in a failed payment. If the payment
// succeeds, then a non-nil Route 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) SendToRoute(routes []*route.Route,
payment *LightningPayment) ([32]byte, *route.Route, error) {
// SendToRoute attempts to send a payment with the given hash through the
// provided route. This function is blocking and will return the obtained
// preimage if the payment is successful or the full error in case of a failure.
func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, route *route.Route) (
lntypes.Preimage, error) {
paySession := r.missionControl.NewPaymentSessionFromRoutes(
routes,
)
// Create a payment session for just this route.
paySession := r.missionControl.NewPaymentSessionForRoute(route)
return r.sendPayment(payment, paySession)
// Create a (mostly) dummy payment, as the created payment session is
// not going to do path finding.
payment := &LightningPayment{
PaymentHash: hash,
}
preimage, _, err := r.sendPayment(payment, paySession)
return preimage, err
}
// sendPayment attempts to send a payment as described within the passed
+4 -3
View File
@@ -18,6 +18,7 @@ import (
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/zpay32"
@@ -407,12 +408,12 @@ func TestChannelUpdateValidation(t *testing.T) {
// The payment parameter is mostly redundant in SendToRoute. Can be left
// empty for this test.
payment := &LightningPayment{}
var payment lntypes.Hash
// Send off the payment request to the router. The specified route
// should be attempted and the channel update should be received by
// router and ignored because it is missing a valid signature.
_, _, err = ctx.router.SendToRoute([]*route.Route{rt}, payment)
_, err = ctx.router.SendToRoute(payment, rt)
if err == nil {
t.Fatalf("expected route to fail with channel update")
}
@@ -445,7 +446,7 @@ func TestChannelUpdateValidation(t *testing.T) {
}
// Retry the payment using the same route as before.
_, _, err = ctx.router.SendToRoute([]*route.Route{rt}, payment)
_, err = ctx.router.SendToRoute(payment, rt)
if err == nil {
t.Fatalf("expected route to fail with channel update")
}