}
}
-fn extract_invoice<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage) -> (Bolt12Invoice, Option<BlindedMessagePath>) {
+fn extract_invoice<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage) -> (Bolt12Invoice, BlindedMessagePath) {
match node.onion_messenger.peel_onion_message(message) {
Ok(PeeledOnion::Receive(message, _, reply_path)) => match message {
ParsedOnionMessageContents::Offers(offers_message) => match offers_message {
OffersMessage::InvoiceRequest(invoice_request) => panic!("Unexpected invoice_request: {:?}", invoice_request),
- OffersMessage::Invoice(invoice) => (invoice, reply_path),
+ OffersMessage::Invoice(invoice) => (invoice, reply_path.unwrap()),
#[cfg(async_payments)]
OffersMessage::StaticInvoice(invoice) => panic!("Unexpected static invoice: {:?}", invoice),
OffersMessage::InvoiceError(error) => panic!("Unexpected invoice_error: {:?}", error),
let onion_message = charlie.onion_messenger.next_onion_message_for_peer(david_id).unwrap();
david.onion_messenger.handle_onion_message(&charlie_id, &onion_message);
- let (invoice, _) = extract_invoice(david, &onion_message);
+ let (invoice, reply_path) = extract_invoice(david, &onion_message);
assert_eq!(invoice.amount_msats(), 10_000_000);
assert_ne!(invoice.signing_pubkey(), alice_id);
assert!(!invoice.payment_paths().is_empty());
for path in invoice.payment_paths() {
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
+ // Both Bob and Charlie have an equal number of channels and need to be connected
+ // to Alice when she's handling the message. Therefore, either Bob or Charlie could
+ // serve as the introduction node for the reply path back to Alice.
+ assert!(
+ matches!(
+ reply_path.introduction_node(),
+ &IntroductionNode::NodeId(node_id) if node_id == bob_id || node_id == charlie_id,
+ )
+ );
route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
expect_recent_payment!(david, RecentPaymentDetails::Pending, payment_id);
let onion_message = charlie.onion_messenger.next_onion_message_for_peer(david_id).unwrap();
david.onion_messenger.handle_onion_message(&charlie_id, &onion_message);
- let (invoice, _) = extract_invoice(david, &onion_message);
+ let (invoice, reply_path) = extract_invoice(david, &onion_message);
assert_eq!(invoice, expected_invoice);
assert_eq!(invoice.amount_msats(), 10_000_000);
for path in invoice.payment_paths() {
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(bob_id));
+
route_bolt12_payment(david, &[charlie, bob, alice], &invoice);
expect_recent_payment!(david, RecentPaymentDetails::Pending, payment_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);
- let (invoice, _) = extract_invoice(bob, &onion_message);
+ let (invoice, reply_path) = extract_invoice(bob, &onion_message);
assert_eq!(invoice.amount_msats(), 10_000_000);
assert_ne!(invoice.signing_pubkey(), alice_id);
assert!(!invoice.payment_paths().is_empty());
for path in invoice.payment_paths() {
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(alice_id));
route_bolt12_payment(bob, &[alice], &invoice);
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_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);
- let (invoice, _) = extract_invoice(bob, &onion_message);
+ let (invoice, reply_path) = extract_invoice(bob, &onion_message);
assert_eq!(invoice, expected_invoice);
assert_eq!(invoice.amount_msats(), 10_000_000);
for path in invoice.payment_paths() {
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(alice_id));
}
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(alice_id));
route_bolt12_payment(bob, &[alice], &invoice);
expect_recent_payment!(bob, RecentPaymentDetails::Pending, 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().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();
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().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()));
}
/// Checks that a deferred invoice can be paid asynchronously from an Event::InvoiceReceived.
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
bob.onion_messenger.handle_onion_message(&alice_id, &onion_message);
- let (invoice, _) = extract_invoice(bob, &onion_message);
+ let (invoice, reply_path) = extract_invoice(bob, &onion_message);
assert_ne!(invoice.signing_pubkey(), alice_id);
assert!(!invoice.payment_paths().is_empty());
for path in invoice.payment_paths() {
assert_eq!(path.introduction_node(), &IntroductionNode::NodeId(bob_id));
}
+ assert_eq!(reply_path.introduction_node(), &IntroductionNode::NodeId(bob_id));
route_bolt12_payment(bob, &[alice], &invoice);
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
- let (invoice, _) = extract_invoice(bob, &onion_message);
+ let (invoice, _reply_path) = extract_invoice(bob, &onion_message);
assert_eq!(invoice, expected_invoice);
assert_ne!(invoice.signing_pubkey(), alice_id);
assert!(!invoice.payment_paths().is_empty());