routing: consolidate final hop params for newRoute
This commit creates a wrapper struct, grouping all parameters that influence the final hop during route construction. This is a preliminary step for passing in the receiver's invoice feature bits, which will be used to select an appropriate payment or payload type.
This commit is contained in:
parent
71e05e05bf
commit
495ae8ca42
@ -96,17 +96,29 @@ type edgePolicyWithSource struct {
|
||||
edge *channeldb.ChannelEdgePolicy
|
||||
}
|
||||
|
||||
// newRoute returns a fully valid route between the source and target that's
|
||||
// capable of supporting a payment of `amtToSend` after fees are fully
|
||||
// computed. If the route is too long, or the selected path cannot support the
|
||||
// fully payment including fees, then a non-nil error is returned.
|
||||
// finalHopParams encapsulates various parameters for route construction that
|
||||
// apply to the final hop in a route. These features include basic payment data
|
||||
// such as amounts and cltvs, as well as more complex features like destination
|
||||
// custom records.
|
||||
type finalHopParams struct {
|
||||
amt lnwire.MilliSatoshi
|
||||
cltvDelta uint16
|
||||
records record.CustomSet
|
||||
}
|
||||
|
||||
// newRoute constructs a route using the provided path and final hop constraints.
|
||||
// Any destination specific fields from the final hop params will be attached
|
||||
// assuming the destination's feature vector signals support, otherwise this
|
||||
// method will fail. If the route is too long, or the selected path cannot
|
||||
// support the fully payment including fees, then a non-nil error is returned.
|
||||
//
|
||||
// NOTE: The passed slice of ChannelHops MUST be sorted in forward order: from
|
||||
// the source to the target node of the path finding attempt.
|
||||
func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex,
|
||||
// the source to the target node of the path finding attempt. It is assumed that
|
||||
// any feature vectors on all hops have been validated for transitive
|
||||
// dependencies.
|
||||
func newRoute(sourceVertex route.Vertex,
|
||||
pathEdges []*channeldb.ChannelEdgePolicy, currentHeight uint32,
|
||||
finalCLTVDelta uint16,
|
||||
destCustomRecords record.CustomSet) (*route.Route, error) {
|
||||
finalHop finalHopParams) (*route.Route, error) {
|
||||
|
||||
var (
|
||||
hops []*route.Hop
|
||||
@ -132,7 +144,7 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex,
|
||||
// If this is the last hop, then the hop payload will contain
|
||||
// the exact amount. In BOLT #4: Onion Routing
|
||||
// Protocol / "Payload for the Last Node", this is detailed.
|
||||
amtToForward := amtToSend
|
||||
amtToForward := finalHop.amt
|
||||
|
||||
// Fee is not part of the hop payload, but only used for
|
||||
// reporting through RPC. Set to zero for the final hop.
|
||||
@ -161,9 +173,9 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex,
|
||||
// As this is the last hop, we'll use the specified
|
||||
// final CLTV delta value instead of the value from the
|
||||
// last link in the route.
|
||||
totalTimeLock += uint32(finalCLTVDelta)
|
||||
totalTimeLock += uint32(finalHop.cltvDelta)
|
||||
|
||||
outgoingTimeLock = currentHeight + uint32(finalCLTVDelta)
|
||||
outgoingTimeLock = currentHeight + uint32(finalHop.cltvDelta)
|
||||
} else {
|
||||
// Next, increment the total timelock of the entire
|
||||
// route such that each hops time lock increases as we
|
||||
@ -204,8 +216,8 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex route.Vertex,
|
||||
|
||||
// If this is the last hop, then we'll populate any TLV records
|
||||
// destined for it.
|
||||
if i == len(pathEdges)-1 && len(destCustomRecords) != 0 {
|
||||
currentHop.CustomRecords = destCustomRecords
|
||||
if i == len(pathEdges)-1 && len(finalHop.records) != 0 {
|
||||
currentHop.CustomRecords = finalHop.records
|
||||
}
|
||||
|
||||
hops = append([]*route.Hop{currentHop}, hops...)
|
||||
|
@ -680,8 +680,12 @@ func TestFindLowestFeePath(t *testing.T) {
|
||||
t.Fatalf("unable to find path: %v", err)
|
||||
}
|
||||
route, err := newRoute(
|
||||
paymentAmt, ctx.source, path, startingHeight,
|
||||
finalHopCLTV, nil,
|
||||
ctx.source, path, startingHeight,
|
||||
finalHopParams{
|
||||
amt: paymentAmt,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create path: %v", err)
|
||||
@ -830,8 +834,12 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
|
||||
}
|
||||
|
||||
route, err := newRoute(
|
||||
paymentAmt, sourceVertex, path, startingHeight,
|
||||
finalHopCLTV, nil,
|
||||
sourceVertex, path, startingHeight,
|
||||
finalHopParams{
|
||||
amt: paymentAmt,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create path: %v", err)
|
||||
@ -1244,9 +1252,12 @@ func TestNewRoute(t *testing.T) {
|
||||
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
route, err := newRoute(
|
||||
testCase.paymentAmount, sourceVertex,
|
||||
testCase.hops, startingHeight, finalHopCLTV,
|
||||
nil,
|
||||
sourceVertex, testCase.hops, startingHeight,
|
||||
finalHopParams{
|
||||
amt: testCase.paymentAmount,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
|
||||
if testCase.expectError {
|
||||
@ -2210,8 +2221,12 @@ func TestRestrictOutgoingChannel(t *testing.T) {
|
||||
t.Fatalf("unable to find path: %v", err)
|
||||
}
|
||||
route, err := newRoute(
|
||||
paymentAmt, ctx.source, path, startingHeight,
|
||||
finalHopCLTV, nil,
|
||||
ctx.source, path, startingHeight,
|
||||
finalHopParams{
|
||||
amt: paymentAmt,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create path: %v", err)
|
||||
@ -2336,8 +2351,12 @@ func testCltvLimit(t *testing.T, limit uint32, expectedChannel uint64) {
|
||||
finalHopCLTV = 1
|
||||
)
|
||||
route, err := newRoute(
|
||||
paymentAmt, ctx.source, path, startingHeight, finalHopCLTV,
|
||||
nil,
|
||||
ctx.source, path, startingHeight,
|
||||
finalHopParams{
|
||||
amt: paymentAmt,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create path: %v", err)
|
||||
@ -2623,8 +2642,12 @@ func TestNoCycle(t *testing.T) {
|
||||
t.Fatalf("unable to find path: %v", err)
|
||||
}
|
||||
route, err := newRoute(
|
||||
paymentAmt, ctx.source, path, startingHeight,
|
||||
finalHopCLTV, nil,
|
||||
ctx.source, path, startingHeight,
|
||||
finalHopParams{
|
||||
amt: paymentAmt,
|
||||
cltvDelta: finalHopCLTV,
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create path: %v", err)
|
||||
|
@ -129,8 +129,12 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment,
|
||||
// a route by applying the time-lock and fee requirements.
|
||||
sourceVertex := route.Vertex(ss.SelfNode.PubKeyBytes)
|
||||
route, err := newRoute(
|
||||
payment.Amount, sourceVertex, path, height, finalCltvDelta,
|
||||
payment.DestCustomRecords,
|
||||
sourceVertex, path, height,
|
||||
finalHopParams{
|
||||
amt: payment.Amount,
|
||||
cltvDelta: finalCltvDelta,
|
||||
records: payment.DestCustomRecords,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
// TODO(roasbeef): return which edge/vertex didn't work
|
||||
|
@ -1454,8 +1454,12 @@ func (r *ChannelRouter) FindRoute(source, target route.Vertex,
|
||||
|
||||
// Create the route with absolute time lock values.
|
||||
route, err := newRoute(
|
||||
amt, source, path, uint32(currentHeight), finalCLTVDelta,
|
||||
destCustomRecords,
|
||||
source, path, uint32(currentHeight),
|
||||
finalHopParams{
|
||||
amt: amt,
|
||||
cltvDelta: finalCLTVDelta,
|
||||
records: destCustomRecords,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -2403,7 +2407,11 @@ func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliSatoshi,
|
||||
}
|
||||
|
||||
return newRoute(
|
||||
receiverAmt, source, pathEdges, uint32(height),
|
||||
uint16(finalCltvDelta), nil,
|
||||
source, pathEdges, uint32(height),
|
||||
finalHopParams{
|
||||
amt: receiverAmt,
|
||||
cltvDelta: uint16(finalCltvDelta),
|
||||
records: nil,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user