routing+routerrpc: take max cltv limit into account within path finding

With the introduction of the max CLTV limit parameter, nodes are able to
reject HTLCs that exceed it. This should also be applied to path
finding, otherwise HTLCs crafted by the same node that exceed it never
left the switch. This wasn't a big deal since the previous max CLTV
limit was ~5000 blocks. Once it was lowered to 1008, the issue became
more apparent. Therefore, all of our path finding attempts now have a
restriction of said limit in in order to properly carry out HTLCs to the
network.
This commit is contained in:
Wilmer Paulino committed 2019-10-11 18:04:49 -04:00
1 parent e64493fe5b
commit 0fc401de19
14 files changed
+75 -46

No files matched your search

+3 -3
View File
@@ -260,7 +260,7 @@ type RestrictParams struct {
// CltvLimit is the maximum time lock of the route excluding the final
// ctlv. After path finding is complete, the caller needs to increase
// all cltv expiry heights with the required final cltv delta.
CltvLimit *uint32
CltvLimit uint32
// DestPayloadTLV should be set to true if we need to drop off a TLV
// payload at the final hop in order to properly complete this payment
@@ -495,8 +495,8 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig,
incomingCltv := toNodeDist.incomingCltv +
uint32(timeLockDelta)
// Check that we have cltv limit and that we are within it.
if r.CltvLimit != nil && incomingCltv > *r.CltvLimit {
// Check that we are within our CLTV limit.
if incomingCltv > r.CltvLimit {
return
}
+6 -8
View File
@@ -54,6 +54,7 @@ var (
noRestrictions = &RestrictParams{
FeeLimit: noFeeLimit,
ProbabilitySource: noProbabilitySource,
CltvLimit: math.MaxUint32,
}
testPathFindingConfig = &PathFindingConfig{}
@@ -789,6 +790,7 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
&RestrictParams{
FeeLimit: test.feeLimit,
ProbabilitySource: noProbabilitySource,
CltvLimit: math.MaxUint32,
},
testPathFindingConfig,
sourceNode.PubKeyBytes, target, paymentAmt,
@@ -1916,6 +1918,7 @@ func TestRestrictOutgoingChannel(t *testing.T) {
FeeLimit: noFeeLimit,
OutgoingChannelID: &outgoingChannelID,
ProbabilitySource: noProbabilitySource,
CltvLimit: math.MaxUint32,
},
testPathFindingConfig,
sourceVertex, target, paymentAmt,
@@ -1942,7 +1945,7 @@ func TestRestrictOutgoingChannel(t *testing.T) {
// TestCltvLimit asserts that a cltv limit is obeyed by the path finding
// algorithm.
func TestCltvLimit(t *testing.T) {
t.Run("no limit", func(t *testing.T) { testCltvLimit(t, 0, 1) })
t.Run("no limit", func(t *testing.T) { testCltvLimit(t, 2016, 1) })
t.Run("no path", func(t *testing.T) { testCltvLimit(t, 50, 0) })
t.Run("force high cost", func(t *testing.T) { testCltvLimit(t, 80, 3) })
}
@@ -1998,19 +2001,13 @@ func testCltvLimit(t *testing.T, limit uint32, expectedChannel uint64) {
paymentAmt := lnwire.NewMSatFromSatoshis(100)
target := testGraphInstance.aliasMap["target"]
// Find the best path given the cltv limit.
var cltvLimit *uint32
if limit != 0 {
cltvLimit = &limit
}
path, err := findPath(
&graphParams{
graph: testGraphInstance.graph,
},
&RestrictParams{
FeeLimit: noFeeLimit,
CltvLimit: cltvLimit,
CltvLimit: limit,
ProbabilitySource: noProbabilitySource,
},
testPathFindingConfig,
@@ -2195,6 +2192,7 @@ func testProbabilityRouting(t *testing.T, p10, p11, p20, minProbability float64,
&RestrictParams{
FeeLimit: noFeeLimit,
ProbabilitySource: probabilitySource,
CltvLimit: math.MaxUint32,
},
&PathFindingConfig{
PaymentAttemptPenalty: lnwire.NewMSatFromSatoshis(10),
+4 -9
View File
@@ -73,15 +73,10 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment,
// does not reject the HTLC if some blocks are mined while it's in-flight.
finalCltvDelta += BlockPadding
// If a route cltv limit was specified, we need to subtract the final
// delta before passing it into path finding. The optimal path is
// independent of the final cltv delta and the path finding algorithm is
// unaware of this value.
var cltvLimit *uint32
if payment.CltvLimit != nil {
limit := *payment.CltvLimit - uint32(finalCltvDelta)
cltvLimit = &limit
}
// We need to subtract the final delta before passing it into path
// finding. The optimal path is independent of the final cltv delta and
// the path finding algorithm is unaware of this value.
cltvLimit := payment.CltvLimit - uint32(finalCltvDelta)
// TODO(roasbeef): sync logic amongst dist sys
+2 -2
View File
@@ -20,7 +20,7 @@ func TestRequestRoute(t *testing.T) {
// We expect find path to receive a cltv limit excluding the
// final cltv delta (including the block padding).
if *r.CltvLimit != 22-uint32(BlockPadding) {
if r.CltvLimit != 22-uint32(BlockPadding) {
t.Fatal("wrong cltv limit")
}
@@ -58,7 +58,7 @@ func TestRequestRoute(t *testing.T) {
finalCltvDelta := uint16(8)
payment := &LightningPayment{
CltvLimit: &cltvLimit,
CltvLimit: cltvLimit,
FinalCLTVDelta: finalCltvDelta,
}
+1 -1
View File
@@ -1560,7 +1560,7 @@ type LightningPayment struct {
// CltvLimit is the maximum time lock that is allowed for attempts to
// complete this payment.
CltvLimit *uint32
CltvLimit uint32
// PaymentHash is the r-hash value to use within the HTLC extended to
// the first hop.
+2
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"image/color"
"math"
"math/rand"
"strings"
"sync/atomic"
@@ -219,6 +220,7 @@ func TestFindRoutesWithFeeLimit(t *testing.T) {
restrictions := &RestrictParams{
FeeLimit: lnwire.NewMSatFromSatoshis(10),
ProbabilitySource: noProbabilitySource,
CltvLimit: math.MaxUint32,
}
route, err := ctx.router.FindRoute(