routing: extend path finding to be TLV-EOB aware, allow dest TLV records

In this commit, we extend the path finding to be able to recognize when
a node needs the new TLV format, or the legacy format based on the
feature bits they expose. We also extend the `LightningPayment` struct
to allow the caller to specify an arbitrary set of TLV records which can
be used for a number of use-cases including various variants of
spontaneous payments.
This commit is contained in:
Olaoluwa Osuntokun
2019-07-30 21:41:58 -07:00
parent 5b4c8ac232
commit 4697cfde30
9 changed files with 158 additions and 50 deletions

View File

@@ -670,7 +670,8 @@ func TestFindLowestFeePath(t *testing.T) {
}
route, err := newRoute(
paymentAmt, sourceVertex, path, startingHeight,
finalHopCLTV)
finalHopCLTV, nil,
)
if err != nil {
t.Fatalf("unable to create path: %v", err)
}
@@ -819,7 +820,7 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
route, err := newRoute(
paymentAmt, sourceVertex, path, startingHeight,
finalHopCLTV,
finalHopCLTV, nil,
)
if err != nil {
t.Fatalf("unable to create path: %v", err)
@@ -857,9 +858,15 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
for i := 0; i < len(expectedHops)-1; i++ {
var expectedHop [8]byte
binary.BigEndian.PutUint64(expectedHop[:], route.Hops[i+1].ChannelID)
if !bytes.Equal(sphinxPath[i].HopData.NextAddress[:], expectedHop[:]) {
hopData, err := sphinxPath[i].HopPayload.HopData()
if err != nil {
t.Fatalf("unable to make hop data: %v", err)
}
if !bytes.Equal(hopData.NextAddress[:], expectedHop[:]) {
t.Fatalf("first hop has incorrect next hop: expected %x, got %x",
expectedHop[:], sphinxPath[i].HopData.NextAddress)
expectedHop[:], hopData.NextAddress[:])
}
}
@@ -867,9 +874,15 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
// to indicate it's the exit hop.
var exitHop [8]byte
lastHopIndex := len(expectedHops) - 1
if !bytes.Equal(sphinxPath[lastHopIndex].HopData.NextAddress[:], exitHop[:]) {
hopData, err := sphinxPath[lastHopIndex].HopPayload.HopData()
if err != nil {
t.Fatalf("unable to create hop data: %v", err)
}
if !bytes.Equal(hopData.NextAddress[:], exitHop[:]) {
t.Fatalf("first hop has incorrect next hop: expected %x, got %x",
exitHop[:], sphinxPath[lastHopIndex].HopData.NextAddress)
exitHop[:], hopData.NextAddress)
}
var expectedTotalFee lnwire.MilliSatoshi
@@ -1001,7 +1014,11 @@ func TestNewRoute(t *testing.T) {
timeLockDelta uint16) *channeldb.ChannelEdgePolicy {
return &channeldb.ChannelEdgePolicy{
Node: &channeldb.LightningNode{},
Node: &channeldb.LightningNode{
Features: lnwire.NewFeatureVector(
nil, nil,
),
},
FeeProportionalMillionths: feeRate,
FeeBaseMSat: baseFee,
TimeLockDelta: timeLockDelta,
@@ -1176,9 +1193,11 @@ func TestNewRoute(t *testing.T) {
}
t.Run(testCase.name, func(t *testing.T) {
route, err := newRoute(testCase.paymentAmount,
sourceVertex, testCase.hops, startingHeight,
finalHopCLTV)
route, err := newRoute(
testCase.paymentAmount, sourceVertex,
testCase.hops, startingHeight, finalHopCLTV,
nil,
)
if testCase.expectError {
expectedCode := testCase.expectedErrorCode
@@ -1683,7 +1702,7 @@ func TestPathFindSpecExample(t *testing.T) {
carol := ctx.aliases["C"]
const amt lnwire.MilliSatoshi = 4999999
route, err := ctx.router.FindRoute(
bobNode.PubKeyBytes, carol, amt, noRestrictions,
bobNode.PubKeyBytes, carol, amt, noRestrictions, nil,
)
if err != nil {
t.Fatalf("unable to find route: %v", err)
@@ -1742,7 +1761,7 @@ func TestPathFindSpecExample(t *testing.T) {
// We'll now request a route from A -> B -> C.
route, err = ctx.router.FindRoute(
source.PubKeyBytes, carol, amt, noRestrictions,
source.PubKeyBytes, carol, amt, noRestrictions, nil,
)
if err != nil {
t.Fatalf("unable to find routes: %v", err)
@@ -1925,7 +1944,7 @@ func TestRestrictOutgoingChannel(t *testing.T) {
}
route, err := newRoute(
paymentAmt, sourceVertex, path, startingHeight,
finalHopCLTV,
finalHopCLTV, nil,
)
if err != nil {
t.Fatalf("unable to create path: %v", err)
@@ -2033,6 +2052,7 @@ func testCltvLimit(t *testing.T, limit uint32, expectedChannel uint64) {
)
route, err := newRoute(
paymentAmt, sourceVertex, path, startingHeight, finalHopCLTV,
nil,
)
if err != nil {
t.Fatalf("unable to create path: %v", err)