mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
Advance self blinded payment paths
DefaultRouter will ignore blinded paths where the sender is the introduction node. Similar to message paths, advance such paths by one so that payments may be sent to them.
This commit is contained in:
parent
55ba2aab41
commit
642913c586
4 changed files with 66 additions and 10 deletions
|
@ -4031,8 +4031,8 @@ where
|
|||
self.pending_outbound_payments
|
||||
.send_payment_for_bolt12_invoice(
|
||||
invoice, payment_id, &self.router, self.list_usable_channels(),
|
||||
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer,
|
||||
best_block_height, &self.logger, &self.pending_events,
|
||||
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, &self,
|
||||
&self.secp_ctx, best_block_height, &self.logger, &self.pending_events,
|
||||
|args| self.send_payment_along_path(args)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -986,10 +986,19 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
|
|||
alice.onion_messenger.handle_onion_message(&bob_id, &onion_message);
|
||||
|
||||
let (invoice_request, reply_path) = extract_invoice_request(alice, &onion_message);
|
||||
let payment_context = PaymentContext::Bolt12Offer(Bolt12OfferContext {
|
||||
offer_id: offer.id(),
|
||||
invoice_request: InvoiceRequestFields {
|
||||
payer_id: invoice_request.payer_id(),
|
||||
quantity: None,
|
||||
payer_note_truncated: None,
|
||||
},
|
||||
});
|
||||
assert_ne!(invoice_request.payer_id(), bob_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);
|
||||
|
||||
let invoice = extract_invoice(bob, &onion_message);
|
||||
assert_ne!(invoice.signing_pubkey(), alice_id);
|
||||
|
@ -997,6 +1006,12 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
|
|||
for (_, path) in invoice.payment_paths() {
|
||||
assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id));
|
||||
}
|
||||
|
||||
route_bolt12_payment(bob, &[alice], &invoice);
|
||||
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
|
||||
|
||||
claim_bolt12_payment(bob, &[alice], payment_context);
|
||||
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
|
||||
}
|
||||
|
||||
/// Checks that a refund can be created using an unannounced node as a blinded path's introduction
|
||||
|
|
|
@ -13,6 +13,8 @@ use bitcoin::hashes::Hash;
|
|||
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||
use bitcoin::secp256k1::{self, Secp256k1, SecretKey};
|
||||
|
||||
use crate::blinded_path::{IntroductionNode, NodeIdLookUp};
|
||||
use crate::blinded_path::payment::advance_path_by_one;
|
||||
use crate::events::{self, PaymentFailureReason};
|
||||
use crate::ln::types::{PaymentHash, PaymentPreimage, PaymentSecret};
|
||||
use crate::ln::channel_state::ChannelDetails;
|
||||
|
@ -775,10 +777,13 @@ impl OutboundPayments {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn send_payment_for_bolt12_invoice<R: Deref, ES: Deref, NS: Deref, IH, SP, L: Deref>(
|
||||
pub(super) fn send_payment_for_bolt12_invoice<
|
||||
R: Deref, ES: Deref, NS: Deref, NL: Deref, IH, SP, L: Deref
|
||||
>(
|
||||
&self, invoice: &Bolt12Invoice, payment_id: PaymentId, router: &R,
|
||||
first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
|
||||
best_block_height: u32, logger: &L,
|
||||
node_id_lookup: &NL, secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32,
|
||||
logger: &L,
|
||||
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>,
|
||||
send_payment_along_path: SP,
|
||||
) -> Result<(), Bolt12PaymentError>
|
||||
|
@ -786,6 +791,7 @@ impl OutboundPayments {
|
|||
R::Target: Router,
|
||||
ES::Target: EntropySource,
|
||||
NS::Target: NodeSigner,
|
||||
NL::Target: NodeIdLookUp,
|
||||
L::Target: Logger,
|
||||
IH: Fn() -> InFlightHtlcs,
|
||||
SP: Fn(SendAlongPathArgs) -> Result<(), APIError>,
|
||||
|
@ -807,7 +813,26 @@ impl OutboundPayments {
|
|||
hash_map::Entry::Vacant(_) => return Err(Bolt12PaymentError::UnexpectedInvoice),
|
||||
};
|
||||
|
||||
let payment_params = PaymentParameters::from_bolt12_invoice(&invoice);
|
||||
let mut payment_params = PaymentParameters::from_bolt12_invoice(&invoice);
|
||||
|
||||
// Advance any blinded path where the introduction node is our node.
|
||||
if let Ok(our_node_id) = node_signer.get_node_id(Recipient::Node) {
|
||||
for (_, path) in payment_params.payee.blinded_route_hints_mut().iter_mut() {
|
||||
let introduction_node_id = match path.introduction_node {
|
||||
IntroductionNode::NodeId(pubkey) => pubkey,
|
||||
IntroductionNode::DirectedShortChannelId(direction, scid) => {
|
||||
match node_id_lookup.next_node_id(scid) {
|
||||
Some(next_node_id) => *direction.select_pubkey(&our_node_id, &next_node_id),
|
||||
None => continue,
|
||||
}
|
||||
},
|
||||
};
|
||||
if introduction_node_id == our_node_id {
|
||||
let _ = advance_path_by_one(path, node_signer, node_id_lookup, secp_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let amount_msat = invoice.amount_msats();
|
||||
let mut route_params = RouteParameters::from_payment_params_and_value(
|
||||
payment_params, amount_msat
|
||||
|
@ -1858,6 +1883,7 @@ mod tests {
|
|||
|
||||
use core::time::Duration;
|
||||
|
||||
use crate::blinded_path::EmptyNodeIdLookUp;
|
||||
use crate::events::{Event, PathFailure, PaymentFailureReason};
|
||||
use crate::ln::types::PaymentHash;
|
||||
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
|
||||
|
@ -2201,6 +2227,7 @@ mod tests {
|
|||
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
|
||||
let scorer = RwLock::new(test_utils::TestScorer::new());
|
||||
let router = test_utils::TestRouter::new(network_graph, &logger, &scorer);
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
|
||||
|
||||
let pending_events = Mutex::new(VecDeque::new());
|
||||
|
@ -2229,7 +2256,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
outbound_payments.send_payment_for_bolt12_invoice(
|
||||
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
|
||||
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
|
||||
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
|
||||
|_| panic!()
|
||||
),
|
||||
Ok(()),
|
||||
);
|
||||
|
@ -2252,6 +2280,7 @@ mod tests {
|
|||
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
|
||||
let scorer = RwLock::new(test_utils::TestScorer::new());
|
||||
let router = test_utils::TestRouter::new(network_graph, &logger, &scorer);
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
|
||||
|
||||
let pending_events = Mutex::new(VecDeque::new());
|
||||
|
@ -2288,7 +2317,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
outbound_payments.send_payment_for_bolt12_invoice(
|
||||
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
|
||||
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
|
||||
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
|
||||
|_| panic!()
|
||||
),
|
||||
Ok(()),
|
||||
);
|
||||
|
@ -2311,6 +2341,7 @@ mod tests {
|
|||
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
|
||||
let scorer = RwLock::new(test_utils::TestScorer::new());
|
||||
let router = test_utils::TestRouter::new(network_graph, &logger, &scorer);
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
|
||||
|
||||
let pending_events = Mutex::new(VecDeque::new());
|
||||
|
@ -2360,7 +2391,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
outbound_payments.send_payment_for_bolt12_invoice(
|
||||
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
|
||||
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
|
||||
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
|
||||
|_| panic!()
|
||||
),
|
||||
Err(Bolt12PaymentError::UnexpectedInvoice),
|
||||
);
|
||||
|
@ -2377,7 +2409,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
outbound_payments.send_payment_for_bolt12_invoice(
|
||||
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
|
||||
&&keys_manager, 0, &&logger, &pending_events, |_| Ok(())
|
||||
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
|
||||
|_| Ok(())
|
||||
),
|
||||
Ok(()),
|
||||
);
|
||||
|
@ -2387,7 +2420,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
outbound_payments.send_payment_for_bolt12_invoice(
|
||||
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
|
||||
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
|
||||
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
|
||||
|_| panic!()
|
||||
),
|
||||
Err(Bolt12PaymentError::DuplicateInvoice),
|
||||
);
|
||||
|
|
|
@ -1045,6 +1045,13 @@ impl Payee {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn blinded_route_hints_mut(&mut self) -> &mut [(BlindedPayInfo, BlindedPath)] {
|
||||
match self {
|
||||
Self::Blinded { route_hints, .. } => &mut route_hints[..],
|
||||
Self::Clear { .. } => &mut []
|
||||
}
|
||||
}
|
||||
|
||||
fn unblinded_route_hints(&self) -> &[RouteHint] {
|
||||
match self {
|
||||
Self::Blinded { .. } => &[],
|
||||
|
|
Loading…
Add table
Reference in a new issue