Skip to content

Commit d8d01ff

Browse files
committed
Introduce payment dummy hops in DefaultRouter
1 parent 3d50170 commit d8d01ff

File tree

5 files changed

+72
-11
lines changed

5 files changed

+72
-11
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ mod test {
175175
use lightning::onion_message::messenger::{
176176
AOnionMessenger, Destination, MessageRouter, OnionMessagePath, OnionMessenger,
177177
};
178+
use lightning::routing::router::DEFAULT_PAYMENT_DUMMY_HOPS;
178179
use lightning::sign::{KeysManager, NodeSigner, ReceiveAuthKey, Recipient};
179180
use lightning::types::features::InitFeatures;
180181
use lightning::types::payment::PaymentHash;
@@ -419,6 +420,11 @@ mod test {
419420
let updates = get_htlc_update_msgs(&nodes[0], &payee_id);
420421
nodes[1].node.handle_update_add_htlc(payer_id, &updates.update_add_htlcs[0]);
421422
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates.commitment_signed, false, false);
423+
424+
for _ in 0..DEFAULT_PAYMENT_DUMMY_HOPS {
425+
nodes[1].node.process_pending_htlc_forwards();
426+
}
427+
422428
expect_and_process_pending_htlcs(&nodes[1], false);
423429

424430
let claimable_events = nodes[1].node.get_and_clear_pending_events();

lightning/src/ln/async_payments_tests.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use crate::onion_message::messenger::{
5555
use crate::onion_message::offers::OffersMessage;
5656
use crate::onion_message::packet::ParsedOnionMessageContents;
5757
use crate::prelude::*;
58-
use crate::routing::router::{Payee, PaymentParameters};
58+
use crate::routing::router::{Payee, PaymentParameters, DEFAULT_PAYMENT_DUMMY_HOPS};
5959
use crate::sign::NodeSigner;
6060
use crate::sync::Mutex;
6161
use crate::types::features::Bolt12InvoiceFeatures;
@@ -1858,6 +1858,13 @@ fn expired_static_invoice_payment_path() {
18581858
blinded_path
18591859
.advance_path_by_one(&nodes[1].keys_manager, &nodes[1].node, &secp_ctx)
18601860
.unwrap();
1861+
1862+
for _ in 0..DEFAULT_PAYMENT_DUMMY_HOPS {
1863+
blinded_path
1864+
.advance_path_by_one(&nodes[2].keys_manager, &nodes[2].node, &secp_ctx)
1865+
.unwrap();
1866+
}
1867+
18611868
match blinded_path.decrypt_intro_payload(&nodes[2].keys_manager).unwrap().0 {
18621869
BlindedPaymentTlvs::Receive(tlvs) => tlvs.payment_constraints.max_cltv_expiry,
18631870
_ => panic!(),

lightning/src/ln/functional_test_utils.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ use crate::ln::peer_handler::IgnoringMessageHandler;
3939
use crate::ln::types::ChannelId;
4040
use crate::onion_message::messenger::OnionMessenger;
4141
use crate::routing::gossip::{NetworkGraph, NetworkUpdate, P2PGossipSync};
42-
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
42+
use crate::routing::router::{
43+
self, PaymentParameters, Route, RouteParameters, DEFAULT_PAYMENT_DUMMY_HOPS,
44+
};
4345
use crate::sign::{EntropySource, RandomBytes};
4446
use crate::types::features::ChannelTypeFeatures;
4547
use crate::types::features::InitFeatures;
@@ -3550,6 +3552,15 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
35503552
node.node.process_pending_htlc_forwards();
35513553
}
35523554

3555+
if is_last_hop {
3556+
// At the final hop, the incoming packet contains N dummy-hop layers
3557+
// before the real HTLC. Each call to `process_pending_htlc_forwards`
3558+
// strips exactly one dummy layer, so we call it N times.
3559+
for _ in 0..dummy_hop_override.unwrap_or(DEFAULT_PAYMENT_DUMMY_HOPS) {
3560+
node.node.process_pending_htlc_forwards();
3561+
}
3562+
}
3563+
35533564
if is_last_hop && clear_recipient_events {
35543565
let events_2 = node.node.get_and_clear_pending_events();
35553566
if payment_claimable_expected {

lightning/src/ln/offers_tests.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,41 @@ fn creates_offer_with_blinded_path_using_unannounced_introduction_node() {
14101410
route_bolt12_payment(bob, &[alice], &invoice);
14111411
expect_recent_payment!(bob, RecentPaymentDetails::Pending, payment_id);
14121412

1413-
claim_bolt12_payment(bob, &[alice], payment_context, &invoice);
1413+
// Extract PaymentClaimable, verify context, and obtain the payment preimage.
1414+
let recipient = &alice;
1415+
let payment_purpose = match get_event!(recipient, Event::PaymentClaimable) {
1416+
Event::PaymentClaimable { purpose, .. } => purpose,
1417+
_ => panic!("No Event::PaymentClaimable"),
1418+
};
1419+
1420+
let payment_preimage = payment_purpose
1421+
.preimage()
1422+
.expect("No preimage in Event::PaymentClaimable");
1423+
1424+
match payment_purpose {
1425+
PaymentPurpose::Bolt12OfferPayment { payment_context: ctx, .. } => {
1426+
assert_eq!(PaymentContext::Bolt12Offer(ctx), payment_context);
1427+
},
1428+
PaymentPurpose::Bolt12RefundPayment { payment_context: ctx, .. } => {
1429+
assert_eq!(PaymentContext::Bolt12Refund(ctx), payment_context);
1430+
},
1431+
_ => panic!("Unexpected payment purpose: {:?}", payment_purpose),
1432+
};
1433+
1434+
// Build ClaimAlongRouteArgs and compensate for the expected overpayment
1435+
// caused by the payer being the introduction node of the blinded path with
1436+
// dummy hops.
1437+
let expected_paths: &[&[&Node]] = &[&[alice]];
1438+
let args = ClaimAlongRouteArgs::new(
1439+
bob,
1440+
expected_paths,
1441+
payment_preimage,
1442+
).with_expected_extra_total_fees_msat(1000);
1443+
1444+
// Execute the claim and verify the invoice was fulfilled.
1445+
let (inv, _events) = claim_payment_along_route(args);
1446+
assert_eq!(inv, Some(PaidBolt12Invoice::Bolt12Invoice(invoice.clone())));
1447+
14141448
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
14151449
}
14161450

@@ -2425,9 +2459,9 @@ fn rejects_keysend_to_non_static_invoice_path() {
24252459
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash });
24262460
do_pass_along_path(args);
24272461
let mut updates = get_htlc_update_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
2428-
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
2462+
nodes[0].node.handle_update_fail_malformed_htlc(nodes[1].node.get_our_node_id(), &updates.update_fail_malformed_htlcs[0]);
24292463
do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);
2430-
expect_payment_failed_conditions(&nodes[0], payment_hash, true, PaymentFailedConditions::new());
2464+
expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new());
24312465
}
24322466

24332467
#[test]

lightning/src/routing/router.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ pub struct DefaultRouter<
7474
score_params: SP,
7575
}
7676

77+
/// Default number of Dummy Hops
78+
pub const DEFAULT_PAYMENT_DUMMY_HOPS: usize = 3;
79+
7780
impl<
7881
G: Deref<Target = NetworkGraph<L>>,
7982
L: Deref,
@@ -198,9 +201,9 @@ where
198201
})
199202
})
200203
.map(|forward_node| {
201-
BlindedPaymentPath::new(
202-
&[forward_node], recipient, local_node_receive_key, tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA,
203-
&*self.entropy_source, secp_ctx
204+
BlindedPaymentPath::new_with_dummy_hops(
205+
&[forward_node], recipient, DEFAULT_PAYMENT_DUMMY_HOPS, local_node_receive_key, tlvs.clone(), u64::MAX,
206+
MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, secp_ctx
204207
)
205208
})
206209
.take(MAX_PAYMENT_PATHS)
@@ -210,9 +213,9 @@ where
210213
Ok(paths) if !paths.is_empty() => Ok(paths),
211214
_ => {
212215
if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) {
213-
BlindedPaymentPath::new(
214-
&[], recipient, local_node_receive_key, tlvs, u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source,
215-
secp_ctx
216+
BlindedPaymentPath::new_with_dummy_hops(
217+
&[], recipient, DEFAULT_PAYMENT_DUMMY_HOPS, local_node_receive_key, tlvs, u64::MAX,
218+
MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, secp_ctx
216219
).map(|path| vec![path])
217220
} else {
218221
Err(())

0 commit comments

Comments
 (0)