mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-26 14:57:30 +02:00
multi: validate payment params at RPC layer
With this patch, we'll fail out earlier in the cycle in case of some wonky parameters, and not leave zombie payments in the router which currently are not cleaned up.
This commit is contained in:
@@ -238,6 +238,14 @@ func (r *RouterBackend) QueryRoutes(ctx context.Context,
|
||||
if in.FinalCltvDelta != 0 {
|
||||
finalCLTVDelta = uint16(in.FinalCltvDelta)
|
||||
}
|
||||
|
||||
// Do bounds checking without block padding so we don't give routes
|
||||
// that will leave the router in a zombie payment state.
|
||||
err = routing.ValidateCLTVLimit(cltvLimit, finalCLTVDelta, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cltvLimit -= uint32(finalCLTVDelta)
|
||||
|
||||
// Parse destination feature bits.
|
||||
@@ -860,6 +868,15 @@ func (r *RouterBackend) extractIntentFromSendRequest(
|
||||
payIntent.DestFeatures = features
|
||||
}
|
||||
|
||||
// Do bounds checking with the block padding so the router isn't
|
||||
// left with a zombie payment in case the user messes up.
|
||||
err = routing.ValidateCLTVLimit(
|
||||
payIntent.CltvLimit, payIntent.FinalCLTVDelta, true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for disallowed payments to self.
|
||||
if !rpcPayReq.AllowSelfPayment && payIntent.Target == r.SelfNode {
|
||||
return nil, errors.New("self-payments not allowed")
|
||||
|
@@ -37,17 +37,22 @@ var (
|
||||
// and passed onto path finding.
|
||||
func TestQueryRoutes(t *testing.T) {
|
||||
t.Run("no mission control", func(t *testing.T) {
|
||||
testQueryRoutes(t, false, false)
|
||||
testQueryRoutes(t, false, false, true)
|
||||
})
|
||||
t.Run("no mission control and msat", func(t *testing.T) {
|
||||
testQueryRoutes(t, false, true)
|
||||
testQueryRoutes(t, false, true, true)
|
||||
})
|
||||
t.Run("with mission control", func(t *testing.T) {
|
||||
testQueryRoutes(t, true, false)
|
||||
testQueryRoutes(t, true, false, true)
|
||||
})
|
||||
t.Run("no mission control bad cltv limit", func(t *testing.T) {
|
||||
testQueryRoutes(t, false, false, false)
|
||||
})
|
||||
}
|
||||
|
||||
func testQueryRoutes(t *testing.T, useMissionControl bool, useMsat bool) {
|
||||
func testQueryRoutes(t *testing.T, useMissionControl bool, useMsat bool,
|
||||
setTimelock bool) {
|
||||
|
||||
ignoreNodeBytes, err := hex.DecodeString(ignoreNodeKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -207,7 +212,21 @@ func testQueryRoutes(t *testing.T, useMissionControl bool, useMsat bool) {
|
||||
},
|
||||
}
|
||||
|
||||
// If this is set, we'll populate MaxTotalTimelock. If this is not set,
|
||||
// the test will fail as CltvLimit will be 0.
|
||||
if setTimelock {
|
||||
backend.MaxTotalTimelock = 1000
|
||||
}
|
||||
|
||||
resp, err := backend.QueryRoutes(context.Background(), request)
|
||||
|
||||
// If no MaxTotalTimelock was set for the QueryRoutes request, make
|
||||
// sure an error was returned.
|
||||
if !setTimelock {
|
||||
require.NotEmpty(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user