') + ')', '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 static invoice creation utils to `ChannelManager` by valentinewallace · Pull Request #3408 · lightningdevkit/rust-lightning · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fuzz/src/chanmon_consistency.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ impl Router for FuzzRouter {

fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
_amount_msats: u64, _secp_ctx: &Secp256k1<T>,
_amount_msats: Option<u64>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPaymentPath>, ()> {
unreachable!()
}
Expand Down
2 changes: 1 addition & 1 deletion fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -160,7 +160,7 @@ impl Router for FuzzRouter {

fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
_amount_msats: u64, _secp_ctx: &Secp256k1<T>,
_amount_msats: Option<u64>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPaymentPath>, ()> {
unreachable!()
}
Expand Down
22 changes: 22 additions & 0 deletions lightning/src/blinded_path/message.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -402,6 +402,24 @@ pub enum AsyncPaymentsContext {
/// containing the expected [`PaymentId`].
hmac: Hmac<Sha256>,
},
/// Context contained within the [`BlindedMessagePath`]s we put in static invoices, provided back
/// to us in corresponding [`HeldHtlcAvailable`] messages.
///
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
InboundPayment {
/// A nonce used for authenticating that a [`HeldHtlcAvailable`] message is valid for a
/// preceding static invoice.
///
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
nonce: Nonce,
/// Authentication code for the [`HeldHtlcAvailable`] message.
///
/// Prevents nodes from creating their own blinded path to us, sending a [`HeldHtlcAvailable`]
/// message and trivially getting notified whenever we come online.
///
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
hmac: Hmac<Sha256>,
},
}

impl_writeable_tlv_based_enum!(MessageContext,
Expand DownExpand Up@@ -433,6 +451,10 @@ impl_writeable_tlv_based_enum!(AsyncPaymentsContext,
(2, nonce, required),
(4, hmac, required),
},
(1, InboundPayment) => {
(0, nonce, required),
(2, hmac, required),
},
);

/// Contains a simple nonce for use in a blinded path's context.
Expand Down
22 changes: 22 additions & 0 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -349,6 +349,11 @@ pub enum PaymentContext {
/// [`Offer`]: crate::offers::offer::Offer
Bolt12Offer(Bolt12OfferContext),

/// The payment was made for a static invoice requested from a BOLT 12 [`Offer`].
///
/// [`Offer`]: crate::offers::offer::Offer
AsyncBolt12Offer(AsyncBolt12OfferContext),

/// The payment was made for an invoice sent for a BOLT 12 [`Refund`].
///
/// [`Refund`]: crate::offers::refund::Refund
Expand DownExpand Up@@ -378,6 +383,18 @@ pub struct Bolt12OfferContext {
pub invoice_request: InvoiceRequestFields,
}

/// The context of a payment made for a static invoice requested from a BOLT 12 [`Offer`].
///
/// [`Offer`]: crate::offers::offer::Offer
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AsyncBolt12OfferContext {

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.

#3427 applies here too, though not sure if it needs to be addressed in this PR.

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.

Tracking this on #2298. I'm inclined to build on Jeff's solution to #3427 to make sure we align with the rest of the offers code unless there are objections.

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.

Opened #3435.

/// The [`Nonce`] used to verify that an inbound [`InvoiceRequest`] corresponds to this static
Comment thread
valentinewallace marked this conversation as resolved.
/// invoice's offer.
///
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
pub offer_nonce: Nonce,
}

/// The context of a payment made for an invoice sent for a BOLT 12 [`Refund`].
///
/// [`Refund`]: crate::offers::refund::Refund
Expand DownExpand Up@@ -627,6 +644,7 @@ impl_writeable_tlv_based_enum_legacy!(PaymentContext,
// 0 for Unknown removed in version 0.1.
(1, Bolt12Offer),
(2, Bolt12Refund),
(3, AsyncBolt12Offer),
);

impl<'a> Writeable for PaymentContextRef<'a> {
Expand All@@ -651,6 +669,10 @@ impl_writeable_tlv_based!(Bolt12OfferContext, {
(2, invoice_request, required),
});

impl_writeable_tlv_based!(AsyncBolt12OfferContext, {
(0, offer_nonce, required),
});

impl_writeable_tlv_based!(Bolt12RefundContext, {});

#[cfg(test)]
Expand Down
22 changes: 14 additions & 8 deletions lightning/src/events/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -181,27 +181,32 @@ impl PaymentPurpose {
pub(crate) fn from_parts(
payment_preimage: Option<PaymentPreimage>, payment_secret: PaymentSecret,
payment_context: Option<PaymentContext>,
) -> Self {
) -> Result<Self, ()> {
match payment_context {
None => {
PaymentPurpose::Bolt11InvoicePayment {
Ok(PaymentPurpose::Bolt11InvoicePayment {
payment_preimage,
payment_secret,
}
})
},
Some(PaymentContext::Bolt12Offer(context)) => {
PaymentPurpose::Bolt12OfferPayment {
Ok(PaymentPurpose::Bolt12OfferPayment {
payment_preimage,
payment_secret,
payment_context: context,
}
})
},
Some(PaymentContext::Bolt12Refund(context)) => {
PaymentPurpose::Bolt12RefundPayment {
Ok(PaymentPurpose::Bolt12RefundPayment {
payment_preimage,
payment_secret,
payment_context: context,
}
})
},
Some(PaymentContext::AsyncBolt12Offer(_context)) => {
// This code will change to return Self::Bolt12OfferPayment when we add support for async
// receive.
Err(())
},
}
}
Expand DownExpand Up@@ -1865,7 +1870,8 @@ impl MaybeReadable for Event {
(13, payment_id, option),
});
let purpose = match payment_secret {
Some(secret) => PaymentPurpose::from_parts(payment_preimage, secret, payment_context),
Some(secret) => PaymentPurpose::from_parts(payment_preimage, secret, payment_context)
.map_err(|()| msgs::DecodeError::InvalidValue)?,
None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()),
None => return Err(msgs::DecodeError::InvalidValue),
};
Expand Down
Loading