-
Notifications
You must be signed in to change notification settings - Fork 368
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
Include a route hint for public, not-yet-announced channels #2024
Include a route hint for public, not-yet-announced channels #2024
Conversation
Codecov ReportPatch coverage:
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## main #2024 +/- ##
==========================================
+ Coverage 91.06% 92.63% +1.56%
==========================================
Files 99 103 +4
Lines 51724 67426 +15702
Branches 51724 67426 +15702
==========================================
+ Hits 47105 62462 +15357
- Misses 4619 4964 +345
... and 72 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
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.
LGTM
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'm not sure about the benefit of including route hints for channels that are not ready yet. IIUC, route hints have the semantics of "you can use these channels to route". If the included channel can't be used to route payments yet, wouldn't we just set the third party trying to pay the invoice up for payment failures that are even worse than the status quo (because they fail only after a delay)?
I see the utility of smoothing out the propagation delay of channel announcements, but maybe for this it would be sufficient to start including the route hints after 5 or 6 confirmations, i.e., when channel readiness is immanent?
We have a separate check for |
Mh, I'm aware of the recent support requests and assumed this may be the use case. If we want to support less than 6 conf channels, couldn't we make the pre-announcement via invoices a) configurable and/or b) dependent on |
Currently if we have any public channel (even an unconfirmed, unusable one) we'll return zero route hints, which guarantees the payment fails if the channel isn't confirmed at 6+ blocks and usable. After this PR, if we have a public channel that has < 7 confirmations but is confirmed we'll include it as a route hint (as long as there are no confirmed public channels), and otherwise fall back to the old behavior. I'm not 100% sure what changes you're asking for - we could make the selection of a channel entirely dependent on channels being Previously we haven't done that because we've tried to be careful around "accidentally" including route hints for private channels (potentially hurting the users' privacy) if there's any public channels. I'm not sure it matters as much anymore with SCID aliases broadly supported, you just reveal that you have a channel, not your specific UTXO used, but its still nice to avoid. We've also tried to include a channel even if its not usable because its better to include something than not, but the code here is starting to get really unwieldy, and I'm not sure its worth trying to maintain that behavior - your channel is probably not going to get confirmed between the time when you issue the invoice and the time someone goes to pay it. |
Ah, from the PR description I was under the impression that we'd now include public channels with some confirmations, even if they are not ready yet. Only now realized that we'd of course still filter by
Yes, still think we should continue to exclude private hints if any public channels are available. |
// If we have a public channel, but it doesn't have enough confirmations to (yet) | ||
// be in the public network graph (and have gotten a chance to propagate), include | ||
// route hints but only for public channels to protect private channel privacy. | ||
channel.is_public |
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.
Shouldn't this still only include the public channel if it has sufficient capacity to route the payment?
channel.is_public | |
has_enough_capacity && channel.is_public |
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.
Won't this result in not including any hints if we have a public channel that isnt yet broadcasted and also doesnt have enough capacity? I mean basically in that case we're screwed anyway, but we might as well include the hint?
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.
Right, and I argue that we should never include a hint for a channel that never will become usable for paying the given invoice. I agree we're screwed anyways, but the UX of the payer side is different: with no route hints the payment fails immediately, with the unusable channel included there is likely a delay for establishing the HTLC along the route, plus some liquidity will be locked unnecessarily while this is in flight. The payer won't be able to simply ignore the route hint as it's the only link to the destination and doesn't include the channel capacity.
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 the reason we did that is because we may have multiple such channels and its possible the sender may find a path through MPP. We could filter them back out at the end if there's only one channel, but...yet more code.
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.
Yes, for the MPP case it's nice to include them anyways, however, we don't do the same for unannounced channels, no? So if we do it here, there will be an inconsistency, as we'll only include hints to private channels that could route the full amount, while for public channels we trust on an aggregate MPP route being present?
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.
Hmm? the branches below check for min_capacity_channel_exists
before checking has_enough_capacity
, so I believe we do?
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.
Sure, just meant to highlight that in case that in case of private channels we have at least a strong preference towards channels that can route the full capacity, while we here now don't for any public channels. Doesn't matter all too much though.
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.
Generally looks good :)! Though leaving some general suggestions and questions:
-
If a user has 2 public channels (to different nodes), one with 7+ confirmations, and second channel that falls within the
has_pub_unconf_chan
case, I think it probably still would make sense to include the second channel as a route hint. Or would we like to keep the current behavior which wouldn't include any route hints at all in this case? -
I guess this is a general comment about our filtering when we have public channels:
If we both public and private channels, and all public channels haveis_useable == false
, but we have private channels withis_useable == true
, I think it would make sense to include those private channels in the route hints. If you agree, we should have the same behavior for ready public channels with< 7 confs
, ie. we should only sethas_pub_unconf_chan
to true ifis_useable
istrue
for that channel.
Maybe this should be done in a separate PR though, if you agree that this should be the intended behavior.
fe5d901
to
10ad8e2
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.
LGTM after squash! Leaving some very nit-picky comments that you may ignore if you prefer to.
10ad8e2
to
3028e88
Compare
Squashed with trivial doc comments applied - $ git diff-tree -U1 10ad8e289 3028e88f8
diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs
index 6b049c700..ad7b03017 100644
--- a/lightning-invoice/src/utils.rs
+++ b/lightning-invoice/src/utils.rs
@@ -514,5 +514,6 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
/// `is_usable` (i.e. the peer is connected).
-/// * If any public channel exists, only public [`RouteHint`]s will be returned,
-/// * If any public, announced channel exists, no [`RouteHint`]s will be returned, as the sender
-/// is expected to find the path by looking at the public channels instead.
+/// * If any public channel exists, only public [`RouteHint`]s will be returned.
+/// * If any public, announced, channel exists (i.e. a channel with 7+ confs, to ensure the
+/// announcement has had a chance to propagate), no [`RouteHint`]s will be returned, as the
+/// sender is expected to find the path by looking at the public channels instead.
fn filter_channels<L: Deref>( |
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.
LGTM! From all the discussion of the different cases to include or filter route hints, would it maybe be helpful to allow the user to make these decisions? It's probably not super necessary until users ask for it, but just a thought
log_trace!(logger, "Not including channels in invoice route hints on account of public channel {}", | ||
log_bytes!(channel.channel_id)); | ||
return vec![] | ||
if channel.confirmations.is_some() && channel.confirmations < Some(7) { |
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.
Is there no constant for min confirmations required for broadcast? The comment below explains things well but just wondering
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.
Looks like no, Channel::get_announcement_sigs
just has a hard-coded conf_height + 5 > cur_height
.
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.
Please excuse the delay here! Generally LGTM, possibly mod the inconsistent behavior regarding the capacity-based filtering discussed above.
// If we have a public channel, but it doesn't have enough confirmations to (yet) | ||
// be in the public network graph (and have gotten a chance to propagate), include | ||
// route hints but only for public channels to protect private channel privacy. | ||
channel.is_public |
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.
Yes, for the MPP case it's nice to include them anyways, however, we don't do the same for unannounced channels, no? So if we do it here, there will be an inconsistency, as we'll only include hints to private channels that could route the full amount, while for public channels we trust on an aggregate MPP route being present?
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.
LGTM, feel free to squash fixups.
If we have a public channel which doesn't yet have six confirmations the network can't possibly know about it as we cannot have announced it yet. However, because we refuse to include route-hints if we have any public channels, we will generate invoices that no one can pay. Thus, if we have any public, not-yet-announced channels, include them as a route-hint.
f2314dc
to
cab6c97
Compare
Squashed fixups. |
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.
LGTM, CI failures are unrelated.
If we have a public channel which doesn't yet have six confirmations the network can't possibly know about it as we cannot have announced it yet. However, because we refuse to include route-hints if we have any public channels, we will generate invoices that no one can pay.
Thus, if we have any public, not-yet-announced channels, include them as a route-hint.