-
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?
Conversation
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
a0bc2cf
to
b3d97b5
Compare
b3d97b5
to
eb1d56a
Compare
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.
Thanks for the quick fix, looking good.
I think a unit-test might be worthwhile for the new behaviour.
@@ -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. |
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 ?
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
why not make isLSP part of ther routerbackend func (s *Server) isLSP
makes it way cleaner ?
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.
I think passing in a function in instead is good enough, also makes it easier to mock in a unit test
@@ -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 comment
The 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:
We just check, does the refChanID exist, if it does we exit early.
_, _, _, err := routerBackend.FetchChannelInfo(refHint.ChannelID)
if err == nil {
return false
}
*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 comment
The reason will be displayed to describe this comment to others. Learn more.
put nolint in a line before.
@@ -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 comment
The 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.
@@ -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 comment
The 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 comment
The 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 FetchChannelCapacity
or FetchChannelEndpoints
, which would return EdgeNotFound
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.
Concept ACK, in principle, a single public hop hint doesn't lead to fee estimation errors, I think. The advantage in checking if we know the last hop is that we'll also probe it and know if it supports the payment as opposed to the case when we assume an LSP.
@@ -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 comment
The 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
@@ -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 comment
The 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 FetchChannelCapacity
or FetchChannelEndpoints
, which would return EdgeNotFound
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 comment
The reason will be displayed to describe this comment to others. Learn more.
could we rename the ref
prefixes to something that's more explanatory?
@hieblmi, remember to re-request review from reviewers when ready |
This PR attempts to fix #9431, an edge case in
EstimateRouteFee
.We want to send a probe in case a route hint contains a public edge.