Add BOLT12 support to LSPS2 via custom Router implementation#4463
Add BOLT12 support to LSPS2 via custom Router implementation#4463tnull wants to merge 9 commits into
Router implementation#4463Conversation
|
👋 Thanks for assigning @jkczyz as a reviewer! |
2cb0546 to
25ab3bc
Compare
|
🔔 1st Reminder Hey @jkczyz! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @jkczyz! This PR has been waiting for your review. |
25ab3bc to
5786409
Compare
|
No issues found. I re-reviewed the full current state of the PR (commit
Security: the decoded payment metadata is authored by the recipient and authenticated via the offer's reply-path context HMAC, so a payer cannot inject malicious LSP parameters. Safe. One low-confidence observation I deliberately did not file: No inline comments posted this pass. |
5786409 to
98a9e9d
Compare
8800d48 to
7ca886d
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4463 +/- ##
==========================================
+ Coverage 87.08% 87.13% +0.04%
==========================================
Files 161 162 +1
Lines 109255 109707 +452
Branches 109255 109707 +452
==========================================
+ Hits 95147 95589 +442
- Misses 11627 11632 +5
- Partials 2481 2486 +5
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:
|
7ca886d to
2ff16d7
Compare
bcc4e10 to
5602e07
Compare
ea05389 to
3acf915
Compare
|
🔔 2nd Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
|
🔔 3rd Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
| pub fn register_intercept_scid( | ||
| &self, intercept_scid: u64, invoice_params: LSPS2Bolt12InvoiceParameters, | ||
| ) -> Option<LSPS2Bolt12InvoiceParameters> { | ||
| debug_assert_eq!(intercept_scid, invoice_params.intercept_scid); |
There was a problem hiding this comment.
lol why on earth are we providing both just to assert that they're the same?
There was a problem hiding this comment.
Because I found it preferable to still communicate that the parameters will be keyed by intercept SCID, especially since we also want to remove them by intercept SCID. And dropping the intercept SCID from the parameters is also not great.
a0bcfcf to
0cef8dc
Compare
|
Addressed pending comments, also had to rebase as we now had a minor conflict. Let me know if I can squash. |
| self.check_refresh_async_receive_offer_cache(false).unwrap(); | ||
| } | ||
|
|
||
| /// Requests fresh async receive offer paths from the configured static invoice server, if any. |
There was a problem hiding this comment.
Why do we need a public version of this? We already do it on timer tick and any time we connect to a peer, istm this is entirely redundant.
There was a problem hiding this comment.
Exactly because we auto-request offers when connecting to a peer we found that we need this refresh during the LDK Node integration. Otherwise, there would already a refresh without the intercept SCIDs inflight when we start negotiating the LSPS2 flow and start injecting the SCIDs, which fails the flow. The alternative workaround would be a busy-loop that calls timer_tick_occurred until we can successfully generate an offer, but that's way uglier, hence why we added this API.
There was a problem hiding this comment.
Hmm, I don't think this currently works? If we build a static invoice when we connect to peers while we're negotiating LSPS2 (ie we have no LSPS2 parameters configured yet) we'll upload the static invoice to our static invoice storage server and there will be a window during which we cannot receive because the static invoice that is stored is bogus. LSPS2BOLT12Router really needs to fail until we have configured parameters so that we won't upload a bogus static invoice.
The docs here really need to mention that this should never really be required unless using LSPS.
| return Ok(offer); | ||
| } | ||
|
|
||
| self.flow.get_async_receive_offer_ready_future().await; |
There was a problem hiding this comment.
Can't this race? We probably need a bit more smarts in the flow to make sure we always return a pre-completed Future if async offers are already available in a race-free way.
There was a problem hiding this comment.
Can't this race? We probably need a bit more smarts in the flow to make sure we always return a pre-completed Future if async offers are already available in a race-free way.
I'm not quite sure I understand what you mean, could you expand? What would race what?
|
Added back a commit that derives |
|
Does this need updating with the changes from #4584? |
Yes, probably we should now wait for that to land first. |
Allow integrations to intercept blinded onion-message hops that identify the next node by short channel id, so LSPS-style protocols can resolve those hops out of band instead of dropping the message. Co-Authored-By: HAL 9000
4342483 to
e56ea06
Compare
Allow BOLT12 blinded payment paths to be supplemented from LSPS2 parameters decoded out of payment metadata, so recipients can advertise JIT-channel paths without maintaining router-local SCID state. Co-Authored-By: HAL 9000
Allow tests and callers to key offer metadata by offer id without wrapping the identifier. Co-Authored-By: HAL 9000
Let async recipients explicitly refresh receive offers, wait for readiness, and preserve payment metadata across static-invoice refreshes. Co-Authored-By: HAL 9000
Align LSPS2 CLTV deltas with the wire format and the rest of LDK's routing types. Co-Authored-By: HAL 9000
Clarify how LSPS2 invoice parameters relate to BOLT11 route hints and BOLT12 blinded payment path creation. Co-Authored-By: HAL 9000
Let integration tests force specific blinded payment paths so LSPS2 BOLT12 routing behavior can be exercised deterministically. Co-Authored-By: HAL 9000
Exercise decoder-provided LSPS2 parameters across custom-router, end-to-end, compact message path, and async-payment BOLT12 flows. Co-Authored-By: HAL 9000
Record the new LSPS2 BOLT12 routing support and its related compatibility note for the next release notes. Co-Authored-By: HAL 9000
e56ea06 to
26da1dd
Compare
|
Now updated to use the new payment-metadata-in-BOLT12-context flow. Also updated lightningdevkit/ldk-node#817 to use this. |
| /// | ||
| /// The metadata is persisted with the async receive offer cache so future static-invoice | ||
| /// refreshes for the same offer continue to include it. | ||
| pub fn refresh_async_receive_offers_with_payment_metadata( |
There was a problem hiding this comment.
Why do we need this? Doesn't our router inject the metadata for us?
| self.check_refresh_async_receive_offer_cache(false).unwrap(); | ||
| } | ||
|
|
||
| /// Requests fresh async receive offer paths from the configured static invoice server, if any. |
There was a problem hiding this comment.
Hmm, I don't think this currently works? If we build a static invoice when we connect to peers while we're negotiating LSPS2 (ie we have no LSPS2 parameters configured yet) we'll upload the static invoice to our static invoice storage server and there will be a window during which we cannot receive because the static invoice that is stored is bogus. LSPS2BOLT12Router really needs to fail until we have configured parameters so that we won't upload a bogus static invoice.
The docs here really need to mention that this should never really be required unless using LSPS.
Closes #4272.
This is an alternative approach to #4394 which leverages a custom
Routerimplementation on the client side to inject the respective.LDK Node integration PR over at lightningdevkit/ldk-node#817