-
Notifications
You must be signed in to change notification settings - Fork 419
Static invoice server: treat forwarded invoice requests as onion message forwards #4114
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
Static invoice server: treat forwarded invoice requests as onion message forwards #4114
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
NextMessageHop::ShortChannelId(scid) => match self.node_id_lookup.next_node_id(scid) { | ||
Some(pubkey) => pubkey, | ||
None => { | ||
log_trace!(self.logger, "Dropping forwarded onion messager: unable to resolve next hop using SCID {} {}", scid, log_suffix); |
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.
There's a typo in the log message: messager
should be message
to maintain consistency with other error messages in this file.
log_trace!(self.logger, "Dropping forwarded onion messager: unable to resolve next hop using SCID {} {}", scid, log_suffix); | |
log_trace!(self.logger, "Dropping forwarded onion message: unable to resolve next hop using SCID {} {}", scid, log_suffix); |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4114 +/- ##
==========================================
- Coverage 88.72% 88.53% -0.19%
==========================================
Files 177 179 +2
Lines 133286 134333 +1047
Branches 133286 134333 +1047
==========================================
+ Hits 118253 118938 +685
- Misses 12326 12638 +312
- Partials 2707 2757 +50
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
A few small comments, but mostly looks good.
/// recipient is online to provide a new invoice. This path should be persisted and | ||
/// later provided to [`ChannelManager::respond_to_static_invoice_request`]. | ||
/// | ||
/// This path's [`BlindedMessagePath::introduction_node`] MUST be set to our node or one of our |
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 be documented on the client end of the protocol not the server end?
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 generally agree, though the only other possible place I see is on the ServeStaticInvoice
onion message field where no one will see it. Maybe that's fine? There's nothing clients can do in practice to satisfy this requirement right now anyway since LDK generates the path without their intervention, so I guess I'll move it.
Edit: basically duplicated the docs in both places so they are more likely to be surfaced
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
In an upcoming commit, we will need to repurpose this logic when, as a static invoice server node, we update our support for forwarding invoice requests from payers to often-offline recipients. We currently treat these forwarded invreqs as outbound onion messages that are initiated by our node, when they should really be treated as forwarded onion messages.
Makes the next commit cleaner when we add support for forwarding onion messages within send_onion_message_internal. Also rename enqueue_onion_message to specify that it is used for outbound onion messages.
Previously, when a static invoice server forwarded an invoice request to an often-offline recipient, they would treat the outbound message like any other outbound onion message initiated by their own node. That means they would buffer the onion message internally in the onion messenger and generate a ConnectionNeeded event if the next-hop node was offline. Buffering the onion message in this case poses a DoS risk for the invoice server node, since they do not control the quantity of invoice requests they receive on behalf of often-offline recipients. Instead, we should treat these forwarded invoice requests like any other onion message that needs to be forwarded -- if the next-hop node is offline, either drop the message or generate an OnionMessageIntercepted event for it (pushing the DoS management onto the handler of the interception event).
9d3a2bc
to
2460c46
Compare
8c9ceef
to
e0a805f
Compare
Some((features, addresses)) if features.supports_onion_messages() => { | ||
Ok(OnionMessagePath { | ||
intermediate_nodes: vec![], | ||
destination, | ||
first_node_addresses, | ||
first_node_addresses: addresses.to_vec(), | ||
}) | ||
}, |
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.
Maybe we should not do this new always-generate-DC-event behavior if the node is announced, actually?
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.
You mean announced && !supports_onion_messages
? That seems reasonable. Otherwise we could even drop the supports_onion_messages
check now, seems weird to generate the DC event for a peer that doesn't support OMs and just drop the connection addresses lol.
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 didn't follow that -- how can we drop the OM feature check but also avoid generating DC events for non-OM-supporting peers? I pushed what I think is correct.
e0a805f
to
9e2b626
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.
Two comments, otherwise LGTM.
9e2b626
to
b03f377
Compare
Imagine an LSP with a mobile client. The LSP wants to pay an offer that client issued. It generates an onion messages invreq and sends it. The OnionMessenger notices it's not connected and searches the network graph. It doesn't find the mobile client so doesn't create a direct connect event. The message gets dropped and the payment fails. Here we start generating the DC event irrespective of the network graph so the LSP can use LSPS5 to wake the client.
b03f377
to
1bd3f36
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.
Just gonna land this. Its quite straightforward.
Previously, when a static invoice server forwarded an invoice request to an
often-offline recipient, they would treat the outbound message like any other
outbound onion message initiated by their own node. That means they would
buffer the onion message internally in the onion messenger and generate a
ConnectionNeeded
event if the next-hop node was offline.Buffering the onion message in this case poses a DoS risk for the invoice
server node, since they do not control the quantity of invoice requests they
receive on behalf of often-offline recipients. Instead, we should treat these
forwarded invoice requests like any other onion message that needs to be
forwarded -- if the next-hop node is offline, either drop the message or
generate an
OnionMessageIntercepted
event for it (pushing the DoS managementonto the handler of the interception event).
Closes #4110
Also closes #4112:
Imagine an LSP with a mobile client. The LSP wants to pay an offer that client
issued. It generates an onion messages invreq and sends it. The OnionMessenger
notices it's not connected and searches the network graph. It doesn't find the
mobile client so doesn't create a direct connect event. The message gets
dropped and the payment fails.
Here we start generating the DC event irrespective of the network graph so the
LSP can use LSPS5 to wake the client.