-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
routerrpc: fix estimateroutefee for public route hints #9433
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ import ( | |
"github.com/lightningnetwork/lnd/channeldb" | ||
"github.com/lightningnetwork/lnd/feature" | ||
"github.com/lightningnetwork/lnd/fn/v2" | ||
"github.com/lightningnetwork/lnd/graph/db/models" | ||
"github.com/lightningnetwork/lnd/htlcswitch" | ||
"github.com/lightningnetwork/lnd/lnrpc" | ||
"github.com/lightningnetwork/lnd/lntypes" | ||
|
@@ -44,6 +45,11 @@ type RouterBackend struct { | |
// SelfNode is the vertex of the node sending the payment. | ||
SelfNode route.Vertex | ||
|
||
// FetchChannelInfo is a closure that we'll use the fetch the latest | ||
// routing state for a particular channel identified by its channel ID. | ||
FetchChannelInfo func(chanID uint64) (*models.ChannelEdgeInfo, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although we are currently only interested in a bool return value, we might still return the full chaninfo as a prevision for future use case, hmm I am not sure maybe we just simplify the function signature for now and only return a bool (also then maybe changing the name of the function)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also repurpose some of the other endpoints exposed here already, like |
||
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) | ||
|
||
// FetchChannelCapacity is a closure that we'll use the fetch the total | ||
// capacity of a channel to populate in responses. | ||
FetchChannelCapacity func(chanID uint64) (btcutil.Amount, error) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ import ( | |
"github.com/lightningnetwork/lnd/aliasmgr" | ||
"github.com/lightningnetwork/lnd/channeldb" | ||
"github.com/lightningnetwork/lnd/fn/v2" | ||
graphdb "github.com/lightningnetwork/lnd/graph/db" | ||
"github.com/lightningnetwork/lnd/lnrpc" | ||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" | ||
"github.com/lightningnetwork/lnd/lntypes" | ||
|
@@ -552,7 +553,7 @@ func (s *Server) probePaymentRequest(ctx context.Context, paymentRequest string, | |
// If the hints don't indicate an LSP then chances are that our probe | ||
// payment won't be blocked along the route to the destination. We send | ||
// a probe payment with unmodified route hints. | ||
if !isLSP(hints) { | ||
if !isLSP(hints, s.cfg.RouterBackend) { | ||
probeRequest.RouteHints = invoicesrpc.CreateRPCRouteHints(hints) | ||
return s.sendProbePayment(ctx, probeRequest) | ||
} | ||
|
@@ -627,12 +628,13 @@ func (s *Server) probePaymentRequest(ctx context.Context, paymentRequest string, | |
// isLSP checks if the route hints indicate an LSP. An LSP is indicated with | ||
// true if the last node in each route hint has the same node id, false | ||
// otherwise. | ||
func isLSP(routeHints [][]zpay32.HopHint) bool { | ||
func isLSP(routeHints [][]zpay32.HopHint, routerBackend *RouterBackend) bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not make isLSP part of ther routerbackend There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think passing in a function in instead is good enough, also makes it easier to mock in a unit test |
||
if len(routeHints) == 0 || len(routeHints[0]) == 0 { | ||
return false | ||
} | ||
|
||
refNodeID := routeHints[0][len(routeHints[0])-1].NodeID | ||
refHint := routeHints[0][len(routeHints[0])-1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we rename the |
||
refNodeID := refHint.NodeID | ||
for i := 1; i < len(routeHints); i++ { | ||
// Skip empty route hints. | ||
if len(routeHints[i]) == 0 { | ||
|
@@ -649,7 +651,16 @@ func isLSP(routeHints [][]zpay32.HopHint) bool { | |
} | ||
} | ||
|
||
return true | ||
// If the ref node hint contains a public channel we can send a probe to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's move it at the beginning so we can do the check first something like this:
|
||
// it directly, hence don't signal an LSP. | ||
_, _, _, err := routerBackend.FetchChannelInfo(refHint.ChannelID) | ||
if errors.Is(err, graphdb.ErrEdgeNotFound) { | ||
return true | ||
} | ||
|
||
// The ref node hint contains a public channel, so we don't signal an | ||
// LSP. | ||
return false | ||
} | ||
|
||
// prepareLspRouteHints assumes that the isLsp heuristic returned true for the | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package routerrpc | |
|
||
import ( | ||
"context" | ||
"github.com/lightningnetwork/lnd/graph/db/models" | ||
"testing" | ||
"time" | ||
|
||
|
@@ -387,7 +388,13 @@ func TestIsLsp(t *testing.T) { | |
|
||
for _, tc := range lspTestCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
require.Equal(t, tc.isLsp, isLSP(tc.routeHints)) | ||
require.Equal(t, tc.isLsp, isLSP(tc.routeHints, &RouterBackend{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it makes sense to add a unit test for this behaviour. |
||
FetchChannelInfo: func(chanID uint64) (*models.ChannelEdgeInfo, | ||
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { | ||
|
||
return nil, nil, nil, nil | ||
}, | ||
})) | ||
if !tc.isLsp { | ||
return | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -698,6 +698,17 @@ func (r *rpcServer) addDeps(s *server, macService *macaroons.Service, | |
|
||
routerBackend := &routerrpc.RouterBackend{ | ||
SelfNode: selfNode.PubKeyBytes, | ||
FetchChannelInfo: func(chanID uint64) (*models.ChannelEdgeInfo, | ||
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, | ||
error) { | ||
|
||
info, policy1, policy2, err := graph.FetchChannelEdgesByID(chanID) //nolint:ll | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put nolint in a line before. |
||
if err != nil { | ||
return nil, nil, nil, err | ||
} | ||
|
||
return info, policy1, policy2, nil | ||
}, | ||
FetchChannelCapacity: func(chanID uint64) (btcutil.Amount, | ||
error) { | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
routing state? maybe just write ChannelPolicy ?