Works towards making the inner BlindedPath struct private to the module.
/// A [`BlindedPath`] to be used for sending or receiving a message, hiding the identity of the
/// recipient.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-pub struct BlindedMessagePath(pub BlindedPath);
+pub struct BlindedMessagePath(pub(super) BlindedPath);
impl Writeable for BlindedMessagePath {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
pub fn blinded_hops(&self) -> &[BlindedHop] {
&self.0.blinded_hops
}
+
+ pub(crate) fn introduction_node_mut(&mut self) -> &mut IntroductionNode {
+ &mut self.0.introduction_node
+ }
+
+ #[cfg(test)]
+ pub fn from_raw(
+ introduction_node_id: PublicKey, blinding_point: PublicKey, blinded_hops: Vec<BlindedHop>
+ ) -> Self {
+ Self(BlindedPath {
+ introduction_node: IntroductionNode::NodeId(introduction_node_id),
+ blinding_point,
+ blinded_hops,
+ })
+ }
+
+ #[cfg(test)]
+ pub fn clear_blinded_hops(&mut self) {
+ self.0.blinded_hops.clear()
+ }
}
/// An intermediate node, and possibly a short channel id leading to the next node.
for path in offer.paths() {
let introduction_node_id = resolve_introduction_node(bob, &path);
assert_eq!(introduction_node_id, alice_id);
- assert!(matches!(path.0.introduction_node, IntroductionNode::DirectedShortChannelId(..)));
+ assert!(matches!(path.introduction_node(), &IntroductionNode::DirectedShortChannelId(..)));
}
}
assert_eq!(offer.absolute_expiry(), Some(absolute_expiry));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
let offer = alice.node
assert_eq!(offer.absolute_expiry(), None);
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
}
for path in refund.paths() {
let introduction_node_id = resolve_introduction_node(alice, &path);
assert_eq!(introduction_node_id, bob_id);
- assert!(matches!(path.0.introduction_node, IntroductionNode::DirectedShortChannelId(..)));
+ assert!(matches!(path.introduction_node(), &IntroductionNode::DirectedShortChannelId(..)));
}
}
assert_eq!(refund.absolute_expiry(), Some(absolute_expiry));
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
}
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
let payment_id = PaymentId([1; 32]);
});
assert_eq!(invoice_request.amount_msats(), None);
assert_ne!(invoice_request.payer_id(), david_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
let onion_message = alice.onion_messenger.next_onion_message_for_peer(charlie_id).unwrap();
charlie.onion_messenger.handle_onion_message(&alice_id, &onion_message);
assert_ne!(refund.payer_id(), david_id);
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
}
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
let payment_id = PaymentId([1; 32]);
});
assert_eq!(invoice_request.amount_msats(), None);
assert_ne!(invoice_request.payer_id(), bob_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(bob_id));
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
bob.onion_messenger.handle_onion_message(&alice_id, &onion_message);
assert_ne!(refund.payer_id(), bob_id);
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
expect_recent_payment!(bob, RecentPaymentDetails::AwaitingInvoice, payment_id);
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
let payment_id = PaymentId([1; 32]);
alice.onion_messenger.handle_onion_message(&bob_id, &onion_message);
let (_, reply_path) = extract_invoice_request(alice, &onion_message);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
// Send, extract and verify the second Invoice Request message
let onion_message = david.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
alice.onion_messenger.handle_onion_message(&bob_id, &onion_message);
let (_, reply_path) = extract_invoice_request(alice, &onion_message);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(nodes[6].node.get_our_node_id()));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(nodes[6].node.get_our_node_id()));
}
/// This test checks that when multiple potential introduction nodes are available for the payee,
.build().unwrap();
assert_ne!(refund.payer_id(), alice_id);
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
expect_recent_payment!(alice, RecentPaymentDetails::AwaitingInvoice, payment_id);
let onion_message = bob.onion_messenger.next_onion_message_for_peer(alice_id).unwrap();
let (_, reply_path) = extract_invoice(alice, &onion_message);
- assert_eq!(reply_path.unwrap().0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.unwrap().introduction_node(), &IntroductionNode::NodeId(charlie_id));
// Send, extract and verify the second Invoice Request message
let onion_message = david.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
let onion_message = bob.onion_messenger.next_onion_message_for_peer(alice_id).unwrap();
let (_, reply_path) = extract_invoice(alice, &onion_message);
- assert_eq!(reply_path.unwrap().0.introduction_node, IntroductionNode::NodeId(nodes[6].node.get_our_node_id()));
+ assert_eq!(reply_path.unwrap().introduction_node(), &IntroductionNode::NodeId(nodes[6].node.get_our_node_id()));
}
/// Checks that a deferred invoice can be paid asynchronously from an Event::InvoiceReceived.
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
let payment_id = PaymentId([1; 32]);
},
});
assert_ne!(invoice_request.payer_id(), bob_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(alice_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(alice_id));
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
bob.onion_messenger.handle_onion_message(&alice_id, &onion_message);
assert_ne!(refund.payer_id(), bob_id);
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(alice_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
expect_recent_payment!(bob, RecentPaymentDetails::AwaitingInvoice, payment_id);
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
let invalid_path = alice.node
.build().unwrap()
.paths().first().unwrap()
.clone();
- assert_eq!(invalid_path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(invalid_path.introduction_node(), &IntroductionNode::NodeId(bob_id));
// Send the invoice request directly to Alice instead of using a blinded path.
let payment_id = PaymentId([1; 32]);
let (invoice_request, reply_path) = extract_invoice_request(alice, &onion_message);
assert_eq!(invoice_request.amount_msats(), None);
assert_ne!(invoice_request.payer_id(), david_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
assert_eq!(alice.onion_messenger.next_onion_message_for_peer(charlie_id), None);
let (invoice_request, reply_path) = extract_invoice_request(alice, &onion_message);
assert_eq!(invoice_request.amount_msats(), None);
assert_ne!(invoice_request.payer_id(), david_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
assert_eq!(alice.onion_messenger.next_onion_message_for_peer(charlie_id), None);
}
assert_ne!(offer.signing_pubkey(), Some(alice_id));
assert!(!offer.paths().is_empty());
for path in offer.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(bob_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
// Initiate an invoice request, but abandon tracking it.
let (invoice_request, reply_path) = extract_invoice_request(alice, &onion_message);
assert_eq!(invoice_request.amount_msats(), None);
assert_ne!(invoice_request.payer_id(), david_id);
- assert_eq!(reply_path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
let onion_message = alice.onion_messenger.next_onion_message_for_peer(charlie_id).unwrap();
charlie.onion_messenger.handle_onion_message(&alice_id, &onion_message);
assert_ne!(refund.payer_id(), david_id);
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
}
expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id);
assert_ne!(refund.payer_id(), david_id);
assert!(!refund.paths().is_empty());
for path in refund.paths() {
- assert_eq!(path.0.introduction_node, IntroductionNode::NodeId(charlie_id));
+ assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(charlie_id));
}
let expected_invoice = alice.node.request_refund_payment(&refund).unwrap();
(None, Some(paths)) => {
if !paths
.iter()
- .filter_map(|path| path.0.blinded_hops.last())
+ .filter_map(|path| path.blinded_hops().last())
.any(|last_hop| invoice_signing_pubkey == &last_hop.blinded_node_id)
{
return Err(Bolt12SemanticError::InvalidSigningPubkey);
use core::time::Duration;
- use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+ use crate::blinded_path::BlindedHop;
use crate::blinded_path::message::BlindedMessagePath;
use crate::sign::KeyMaterial;
use crate::ln::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
let nonce = Nonce::from_entropy_source(&entropy);
let secp_ctx = Secp256k1::new();
- let blinded_path = BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ let blinded_path = BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
- ],
- });
+ ]
+ );
#[cfg(c_bindings)]
use crate::offers::offer::OfferWithDerivedMetadataBuilder as OfferBuilder;
let entropy = FixedEntropy {};
let secp_ctx = Secp256k1::new();
- let blinded_path = BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ let blinded_path = BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
- ],
- });
+ ]
+ );
let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
.path(blinded_path)
#[test]
fn parses_invoice_with_node_id_from_blinded_path() {
let paths = vec![
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }),
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ ]
+ ),
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
- ],
- }),
+ ]
+ ),
];
let blinded_node_id_sign = |message: &UnsignedBolt12Invoice| {
.build().unwrap()
.sign(recipient_sign).unwrap();
- let blinded_path = BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ let blinded_path = BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
- ],
- });
+ ]
+ );
let mut tlv_stream = invoice.as_tlv_stream();
let message_paths = vec![blinded_path];
use bitcoin::secp256k1::Secp256k1;
use core::num::NonZeroU64;
use core::time::Duration;
- use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+ use crate::blinded_path::BlindedHop;
use crate::blinded_path::message::BlindedMessagePath;
use crate::sign::KeyMaterial;
use crate::ln::features::OfferFeatures;
let nonce = Nonce::from_entropy_source(&entropy);
let secp_ctx = Secp256k1::new();
- let blinded_path = BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ let blinded_path = BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
- ],
- });
+ ]
+ );
#[cfg(c_bindings)]
use super::OfferWithDerivedMetadataBuilder as OfferBuilder;
#[test]
fn builds_offer_with_paths() {
let paths = vec![
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }),
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ ]
+ ),
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
- ],
- }),
+ ]
+ ),
];
let offer = OfferBuilder::new(pubkey(42))
#[test]
fn parses_offer_with_paths() {
let offer = OfferBuilder::new(pubkey(42))
- .path(BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ .path(BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }))
- .path(BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
- BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
- BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
- ],
- }))
+ ]
+ ))
+ .path(BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
+ BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
+ BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
+ ]
+ ))
.build()
.unwrap();
if let Err(e) = offer.to_string().parse::<Offer>() {
}
let offer = OfferBuilder::new(pubkey(42))
- .path(BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
- BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
- BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }))
+ .path(BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
+ BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
+ BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
+ ]
+ ))
.clear_signing_pubkey()
.build()
.unwrap();
use core::time::Duration;
- use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+ use crate::blinded_path::BlindedHop;
use crate::blinded_path::message::BlindedMessagePath;
use crate::sign::KeyMaterial;
use crate::ln::channelmanager::PaymentId;
let secp_ctx = Secp256k1::new();
let payment_id = PaymentId([1; 32]);
- let blinded_path = BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ let blinded_path = BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: node_id, encrypted_payload: vec![0; 44] },
- ],
- });
+ ]
+ );
let refund = RefundBuilder
::deriving_payer_id(node_id, &expanded_key, nonce, &secp_ctx, 1000, payment_id)
#[test]
fn builds_refund_with_paths() {
let paths = vec![
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }),
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ ]
+ ),
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
- ],
- }),
+ ]
+ ),
];
let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
fn parses_refund_with_optional_fields() {
let past_expiry = Duration::from_secs(0);
let paths = vec![
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
- ],
- }),
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ ]
+ ),
+ BlindedMessagePath::from_raw(
+ pubkey(40), pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
- ],
- }),
+ ]
+ ),
];
let refund = RefundBuilder::new(vec![1; 32], payer_pubkey(), 1000).unwrap()
#[cfg(test)]
mod tests {
use crate::blinded_path::message::BlindedMessagePath;
- use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode};
+ use crate::blinded_path::BlindedHop;
use crate::ln::features::{Bolt12InvoiceFeatures, OfferFeatures};
use crate::ln::inbound_payment::ExpandedKey;
use crate::ln::msgs::DecodeError;
}
fn blinded_path() -> BlindedMessagePath {
- BlindedMessagePath(BlindedPath {
- introduction_node: IntroductionNode::NodeId(pubkey(40)),
- blinding_point: pubkey(41),
- blinded_hops: vec![
+ BlindedMessagePath::from_raw(
+ pubkey(40),
+ pubkey(41),
+ vec![
BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] },
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 44] },
],
- })
+ )
}
#[test]
let intermediate_nodes = [ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }];
let context = MessageContext::Custom(Vec::new());
let mut blinded_path = BlindedMessagePath::new(&intermediate_nodes, nodes[2].node_id, context, &*nodes[2].entropy_source, &secp_ctx).unwrap();
- blinded_path.0.blinded_hops.clear();
+ blinded_path.clear_blinded_hops();
let destination = Destination::BlindedPath(blinded_path);
let err = nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap_err();
assert_eq!(err, SendError::TooFewBlindedHops);
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
-use crate::blinded_path::{BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp};
+use crate::blinded_path::{IntroductionNode, NextMessageHop, NodeIdLookUp};
use crate::blinded_path::message::{advance_path_by_one, BlindedMessagePath, ForwardNode, ForwardTlvs, MessageContext, ReceiveTlvs};
use crate::blinded_path::utils;
use crate::events::{Event, EventHandler, EventsProvider, ReplayEvent};
/// provided [`ReadOnlyNetworkGraph`].
pub fn resolve(&mut self, network_graph: &ReadOnlyNetworkGraph) {
if let Destination::BlindedPath(path) = self {
- if let IntroductionNode::DirectedShortChannelId(..) = path.0.introduction_node {
+ if let IntroductionNode::DirectedShortChannelId(..) = path.introduction_node() {
if let Some(pubkey) = path
.public_introduction_node_id(network_graph)
.and_then(|node_id| node_id.as_pubkey().ok())
{
- path.0.introduction_node = IntroductionNode::NodeId(pubkey);
+ *path.introduction_node_mut() = IntroductionNode::NodeId(pubkey);
}
}
}
pub(super) fn num_hops(&self) -> usize {
match self {
Destination::Node(_) => 1,
- Destination::BlindedPath(BlindedMessagePath(BlindedPath { blinded_hops, .. })) => blinded_hops.len(),
+ Destination::BlindedPath(path) => path.blinded_hops().len(),
}
}
fn first_node(&self) -> Option<PublicKey> {
match self {
Destination::Node(node_id) => Some(*node_id),
- Destination::BlindedPath(BlindedMessagePath(BlindedPath { introduction_node, .. })) => {
- match introduction_node {
+ Destination::BlindedPath(path) => {
+ match path.introduction_node() {
IntroductionNode::NodeId(pubkey) => Some(*pubkey),
IntroductionNode::DirectedShortChannelId(..) => None,
}
NL::Target: NodeIdLookUp,
{
let OnionMessagePath { intermediate_nodes, mut destination, first_node_addresses } = path;
- if let Destination::BlindedPath(BlindedMessagePath(BlindedPath { ref blinded_hops, .. })) = destination {
- if blinded_hops.is_empty() {
+ if let Destination::BlindedPath(ref path) = destination {
+ if path.blinded_hops().is_empty() {
return Err(SendError::TooFewBlindedHops);
}
}
if let Destination::BlindedPath(ref mut blinded_path) = destination {
let our_node_id = node_signer.get_node_id(Recipient::Node)
.map_err(|()| SendError::GetNodeIdFailed)?;
- let introduction_node_id = match blinded_path.0.introduction_node {
- IntroductionNode::NodeId(pubkey) => pubkey,
+ let introduction_node_id = match blinded_path.introduction_node() {
+ IntroductionNode::NodeId(pubkey) => *pubkey,
IntroductionNode::DirectedShortChannelId(direction, scid) => {
- match node_id_lookup.next_node_id(scid) {
+ match node_id_lookup.next_node_id(*scid) {
Some(next_node_id) => *direction.select_pubkey(&our_node_id, &next_node_id),
None => return Err(SendError::UnresolvedIntroductionNode),
}
} else {
match &destination {
Destination::Node(pk) => (*pk, PublicKey::from_secret_key(&secp_ctx, &blinding_secret)),
- Destination::BlindedPath(BlindedMessagePath(BlindedPath { introduction_node, blinding_point, .. })) => {
- match introduction_node {
- IntroductionNode::NodeId(pubkey) => (*pubkey, *blinding_point),
+ Destination::BlindedPath(path) => {
+ match path.introduction_node() {
+ IntroductionNode::NodeId(pubkey) => (*pubkey, path.blinding_point()),
IntroductionNode::DirectedShortChannelId(..) => {
return Err(SendError::UnresolvedIntroductionNode);
},
let (mut intro_node_id_blinding_pt, num_blinded_hops) = match &destination {
Destination::Node(_) => (None, 0),
- Destination::BlindedPath(BlindedMessagePath(BlindedPath { introduction_node, blinding_point, blinded_hops })) => {
- let introduction_node_id = match introduction_node {
+ Destination::BlindedPath(path) => {
+ let introduction_node_id = match path.introduction_node() {
IntroductionNode::NodeId(pubkey) => pubkey,
IntroductionNode::DirectedShortChannelId(..) => {
return Err(SendError::UnresolvedIntroductionNode);
},
};
- (Some((*introduction_node_id, *blinding_point)), blinded_hops.len())
+ (Some((*introduction_node_id, path.blinding_point())), path.blinded_hops().len())
},
};
let num_unblinded_hops = num_hops - num_blinded_hops;