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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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
1 change: 1 addition & 0 deletions fuzz/src/invoice_request_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,6 +113,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/onion_hop_data.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}

Expand All@@ -34,6 +34,6 @@ pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
&&test_utils::TestNodeSigner,
&test_utils::TestNodeSigner,
)>>::read(&mut r, (None, &&node_signer));
}
1 change: 1 addition & 0 deletions fuzz/src/refund_deser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,6 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
next_blinding_override: None,
},
node_id: pubkey(43),
htlc_maximum_msat: 1_000_000_000_000,
Expand Down
23 changes: 18 additions & 5 deletions lightning/src/blinded_path/payment.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
use crate::offers::offer::OfferId;
use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, Writeable, Writer};
use crate::util::ser::{FixedLengthReader, LengthReadableArgs, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer};

use core::mem;
use core::ops::Deref;
Expand DownExpand Up@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
///
/// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
pub features: BlindedHopFeatures,
/// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
/// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
pub next_blinding_override: Option<PublicKey>,

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.

Why didn't we support this to begin with?

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.

IIRC I was under the impression that this field only applies to onion messages (it's required for OMs), not payments. And no one actually sets it for payments, so it never popped up in interop testing. :/

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.

I imagine no one set it ever, because its only useful for some kind of weird frankenstein trampoline afaict? What's the intended usecase for concatenating blinded paths? I mean I suppose we should just do it, but I'm curious why its there.

@valentinewallacevalentinewallaceAug 7, 2024

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.

I think Rusty pointed out here that it can help prevent the intro node from being aware that it's the intro node: lightning/bolts#1182 (comment)? I think this is clarified in lightning/bolts#1182 but still need to review that.

Edit: it is clarified quite a bit in that PR:
Screenshot 2024-08-07 at 3 18 29 PM

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.

Ah, so basically its saying we should send onion messages as a blinded path from us to the intro node, prepended to the real blinded path? Do we do that?

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.

Yes, using next_blinding_override in OMs has always been required to prepend the unblinded path to the intro node.

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.

Oops, I think I misread your message. I'm not sure I follow Rusty's logic, actually. It seems like creating a blinded path from us to the intro node trades off the intro node knowing that they're the intro node for the node prior to the intro node knowing that the next hop is the intro node(?). Unless we set next_blinding_override for every hop in our prepended blinded path, which I suppose is possible.

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.

Ah, I guess I'm still not really understanding why this is here, but its not much complexity to support, sooooo

}

/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
Expand DownExpand Up@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentRelay {
/// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
pub cltv_expiry_delta: u16,
Expand All@@ -248,7 +251,7 @@ pub struct PaymentRelay {
/// Constraints for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct PaymentConstraints {
/// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
pub max_cltv_expiry: u32,
Expand DownExpand Up@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
let features_opt =
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
else { Some(WithoutLength(&self.features)) };
encode_tlv_stream!(w, {
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
Expand DownExpand Up@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
_init_and_read_tlv_stream!(r, {
(1, _padding, option),
(2, scid, option),
(8, next_blinding_override, option),
(10, payment_relay, option),
(12, payment_constraints, required),
(14, features, option),
(14, features, (option, encoding: (BlindedHopFeatures, WithoutLength))),
(65536, payment_secret, option),
(65537, payment_context, (default_value, PaymentContext::unknown())),
});
Expand All@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
next_blinding_override,
features: features.unwrap_or_else(BlindedHopFeatures::empty),
}))
} else {
Expand DownExpand Up@@ -602,6 +607,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 100,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand All@@ -618,6 +624,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value(),
Expand DownExpand Up@@ -675,6 +682,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -691,6 +699,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -726,6 +735,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 5_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand All@@ -742,6 +752,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 2_000,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: u64::max_value()
Expand DownExpand Up@@ -781,6 +792,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 5_000,
Expand All@@ -797,6 +809,7 @@ mod tests {
max_cltv_expiry: 0,
htlc_minimum_msat: 1,
},
next_blinding_override: None,
features: BlindedHopFeatures::empty(),
},
htlc_maximum_msat: 10_000
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/blinded_path/utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ where
}

// Panics if `unblinded_tlvs` length is less than `unblinded_pks` length
pub(super) fn construct_blinded_hops<'a, T, I1, I2>(
pub(crate) fn construct_blinded_hops<'a, T, I1, I2>(
secp_ctx: &Secp256k1<T>, unblinded_pks: I1, mut unblinded_tlvs: I2, session_priv: &SecretKey
) -> Result<Vec<BlindedHop>, secp256k1::Error>
where
Expand Down
Loading