') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Add `ChannelManager::create_bolt11_invoice` by jkczyz · Pull Request #3389 · lightningdevkit/rust-lightning · GitHub
Skip to content

Add ChannelManager::create_bolt11_invoice - #3389

Merged
TheBlueMatt merged 10 commits into
lightningdevkit:mainfrom
jkczyz:2024-10-bolt11-invoice-utils
Nov 11, 2024
Merged

Add ChannelManager::create_bolt11_invoice#3389
TheBlueMatt merged 10 commits into
lightningdevkit:mainfrom
jkczyz:2024-10-bolt11-invoice-utils

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Now that the lightning crate depends on the lightning_invoice crate, the utility functions previously living in the latter can be implemented on ChannelManager. Additionally, the parameters are now moved to a struct in order to remove the increasingly combinatorial blow-up of methods.

The new Bolt11InvoiceParameters is used to determine what values to set in the invoice. Using None for any given parameter results in a reasonable the default or a behavior determined by the ChannelManager as detailed in the documentation.

Fixes#3375

Split Bolt11InvoiceDescription into a version used with references to
the description or description hash in the invoice and an owned version
of these for when constructing an invoice. The latter is useful as it
removes an unnecessary clone and can be used in a future change
specifying either a description or description hash in larger set of
invoice parameters. Since it doesn't use a reference, it can be exposed
in bindings as well.

@vincenzopalazzovincenzopalazzo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I like a lot Bolt11InvoiceParameters solution!

CI failure looks like unrelated

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment threadlightning/src/ln/channelmanager.rs Outdated
/// The description for what the invoice is for, or hash of such description.
pub description: Bolt11InvoiceDescription,

/// The duration since the Unix epoch signifying when the invoice was created. If not set,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth letting users override this? Not quite sure the use-case here.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper utilities allowed it since they didn't use highest seen timestamp in non-std. but maybe that wouldn't allow enough accuracy for invoices with short expirations?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, if someone needs "high accuracy" on their timeout (in a no-std environment) they should do it by rejecting the payment on the receive end, cause the sender can always send after expiry if they really want.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... note that the equivalent behavior in utilities that we deprecate won't be possible with this API. So we can't really leave those as deprecated but still maintain the same behavior without duplicating code. We could remove the parameter from the deprecate methods, but seems we might as well remove them outright if anyone upgrading will need to modify the call site regardless. What do you think?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could drop (some? all?) the no_std utility methods while deprecating the rest. I don't think this is critical functionality to maintain, and I don't think no_std use of LDK is all that common currently (aside from maybe Lexe? And historically Mutiny, of course) and a little bit of breakage for just Lexe seems fine to clean up the interface for everyone else :)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped in latest push and removed duration_since_epoch parameter.

Comment threadlightning/src/ln/invoice_utils.rs
When creating a default Bolt11InvoiceParameters, having an infallible
constructor avoids an unwrap.
@jkczyz
jkczyzforce-pushed the 2024-10-bolt11-invoice-utils branch from 2c6a75a to 8b48b47CompareNovember 6, 2024 19:37

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the ChannelManager doc examples and added a Default implementation of Bolt11InvoiceParameters.

Comment threadlightning/src/ln/channelmanager.rs Outdated
/// The description for what the invoice is for, or hash of such description.
pub description: Bolt11InvoiceDescription,

/// The duration since the Unix epoch signifying when the invoice was created. If not set,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... note that the equivalent behavior in utilities that we deprecate won't be possible with this API. So we can't really leave those as deprecated but still maintain the same behavior without duplicating code. We could remove the parameter from the deprecate methods, but seems we might as well remove them outright if anyone upgrading will need to modify the call site regardless. What do you think?

@codecov

codecovBot commented Nov 6, 2024

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 64.18605% with 77 lines in your changes missing coverage. Please review.

Project coverage is 89.62%. Comparing base (2c1e828) to head (7878801).
Report is 398 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/invoice_utils.rs68.57%44 Missing ⚠️
lightning/src/ln/channelmanager.rs58.33%20 Missing and 5 partials ⚠️
lightning-invoice/src/lib.rs46.66%8 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3389 +/- ##
==========================================
+ Coverage 89.57% 89.62% +0.04% 
==========================================
Files 125 128 +3 Lines 101756 104907 +3151 Branches 101756 104907 +3151 ==========================================
+ Hits 91151 94019 +2868 - Misses 7884 8175 +291 + Partials 2721 2713 -8 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jkczyz
jkczyzforce-pushed the 2024-10-bolt11-invoice-utils branch 2 times, most recently from ffcefff to a9bc217CompareNovember 7, 2024 14:31

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest push fixes broken doc links.

@valentinewallace

Copy link
Copy Markdown
Contributor

CI is still sad

@jkczyz
jkczyzforce-pushed the 2024-10-bolt11-invoice-utils branch from a9bc217 to 998b081CompareNovember 7, 2024 19:05
@jkczyz

Copy link
Copy Markdown
ContributorAuthor

Squashed fixups and fixed a no-std test compilation failure.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically LGTM

Comment threadlightning/src/ln/invoice_utils.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +9111 to +9118
let currency = match currency {
Some(currency) => currency,
None => Network::from_chain_hash(self.chain_hash).map(Into::into).unwrap_or(Currency::Bitcoin),
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering whether it makes sense to support a currency other than the one corresponding to ChannelManager::chain_hash. It won't be receivable by this ChannelManager, IIUC. Kinda seems like a bug that it was supported previously?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping it seems reasonable. @TheBlueMatt Any objections? We'd have to drop it from the deprecated utils, too.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currency now removed.

git diff d7e897c7e266d392149aaec7a99e3aa140af5be5..7878801be79928e0309c079ea117d33a2521b557

Comment threadlightning/src/ln/channelmanager.rs Outdated
The upcoming ChannelManager::create_bolt11_invoice will not support
setting a specific creation time, so remove that functionality from the
invoice_utils functions. This will avoid duplicate code when
deprecating.
@jkczyz
jkczyzforce-pushed the 2024-10-bolt11-invoice-utils branch from 998b081 to d7e897cCompareNovember 7, 2024 23:17
When creating an invoice using a ChannelManager, payments for a specific
ChainHash / Network are only valid. Use the one from the ChannelManager
instead of allowing arbitrary ones in the form of a Currency.
Now that the lightning crate depends on the lightning_invoice crate, the
utility functions previously living in the latter can be implemented on
ChannelManager. Additionally, the parameters are now moved to a struct
in order to remove the increasingly combinatorial blow-up of methods.
The new Bolt11InvoiceParameters is used to determine what values to set
in the invoice. Using None for any given parameter results in a
reasonable the default or a behavior determined by the ChannelManager as
detailed in the documentation.
The utility methods in in invoice_utils will be removed or deprecated in
an upcoming commit.
ChannelManager::create_bolt11_invoice is a simpler and more flexible way
of creating a BOLT11 invoice, so deprecate the corresponding functions
in the invoice_utils module.
Bolt11InvoiceParameters allows for setting currency and
duration_since_epoch. If currency is not set, test that the one
corresponding to ChannelManager's chain hash is usd. If
duration_since_epoch, is not set then highest seen timestamp is used in
non-std compilations.
Update ChannelManager docs to use create_bolt11_invoice and correct
references to modules in the lightning-invoice crate that no longer
exist.
@jkczyz
jkczyzforce-pushed the 2024-10-bolt11-invoice-utils branch from d7e897c to 7878801CompareNovember 8, 2024 18:15
let duration_since_epoch = {
use std::time::SystemTime;
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)
.expect("for the foreseeable future this shouldn't happen")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this panics when time is before 1970, not too far forwards :)

};
#[cfg(not(feature = "std"))]
let duration_since_epoch =
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice to write up a comment here on why its okay to use the timestamp "raw". It could be two hours in the future but generally only like 10-30 minutes in the past. Maybe we should handle short-ish timestamps for no-std clients but its probably fine, just would be good to write down why we think that's okay.

@TheBlueMatt
TheBlueMatt merged commit 739c412 into lightningdevkit:mainNov 11, 2024
@TheBlueMattTheBlueMatt mentioned this pull request Jan 13, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move invoice utilities to ChannelManager

4 participants

@jkczyz@valentinewallace@TheBlueMatt@vincenzopalazzo