Skip to content

Commit 0c0f741

Browse files
shaavancodex
andcommitted
Account for dummy-hop fees in payment test helpers
Update the payment-claim test helpers to compute expected forwarded amounts and dummy-hop skimmed fees from path-ordered HTLC data. This covers both single-path and multi-path blinded payments with dummy hops. Once dummy-hop fees are exposed separately, the helpers can no longer treat the payees amount_msat or the events HTLC ordering as a proxy for the amounts forwarded along each route. PaymentClaimed.htlcs are event-ordered, while dummy TLVs are tracked per expected path. Recover the claimed amounts in expected-path order before recomputing per-path dummy-hop fees, and assert the claimable and claimed fee fields against that reconstructed view. Co-Authored-By: OpenAI Codex <codex@openai.com>
1 parent 125c69e commit 0c0f741

4 files changed

Lines changed: 208 additions & 58 deletions

File tree

lightning/src/ln/async_payments_tests.rs

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -982,12 +982,14 @@ fn ignore_duplicate_invoice() {
982982
check_added_monitors(&sender, 1);
983983

984984
let route: &[&[&Node]] = &[&[always_online_node, async_recipient]];
985+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
985986
let args = PassAlongPathArgs::new(sender, route[0], amt_msat, payment_hash, ev)
986-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
987+
.with_dummy_tlvs(&dummy_tlvs);
987988
let claimable_ev = do_pass_along_path(args).unwrap();
988989
let keysend_preimage = extract_payment_preimage(&claimable_ev);
989-
let (res, _) =
990-
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
990+
let (res, _) = claim_payment_along_route(
991+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
992+
);
991993
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice.clone())));
992994

993995
// After paying the static invoice, check that regular invoice received from async recipient is ignored.
@@ -1063,7 +1065,7 @@ fn ignore_duplicate_invoice() {
10631065

10641066
let args = PassAlongPathArgs::new(sender, route[0], amt_msat, payment_hash, ev)
10651067
.without_clearing_recipient_events()
1066-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1068+
.with_dummy_tlvs(&dummy_tlvs);
10671069
do_pass_along_path(args);
10681070

10691071
let payment_preimage = match get_event!(async_recipient, Event::PaymentClaimable) {
@@ -1072,7 +1074,11 @@ fn ignore_duplicate_invoice() {
10721074
};
10731075

10741076
// After paying invoice, check that static invoice is ignored.
1075-
let res = claim_payment(sender, route[0], payment_preimage);
1077+
let res = claim_payment_along_route(
1078+
ClaimAlongRouteArgs::new(sender, &[route[0]], payment_preimage)
1079+
.with_dummy_tlvs(&dummy_tlvs),
1080+
)
1081+
.0;
10761082
assert_eq!(res, Some(PaidBolt12Invoice::Bolt12Invoice(invoice)));
10771083

10781084
sender.onion_messenger.handle_onion_message(always_online_node_id, &static_invoice_om);
@@ -1138,12 +1144,14 @@ fn async_receive_flow_success() {
11381144
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
11391145

11401146
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
1147+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
11411148
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
1142-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1149+
.with_dummy_tlvs(&dummy_tlvs);
11431150
let claimable_ev = do_pass_along_path(args).unwrap();
11441151
let keysend_preimage = extract_payment_preimage(&claimable_ev);
1145-
let (res, _) =
1146-
claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage));
1152+
let (res, _) = claim_payment_along_route(
1153+
ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
1154+
);
11471155
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));
11481156
}
11491157

@@ -1375,14 +1383,15 @@ fn async_receive_mpp() {
13751383
_ => panic!(),
13761384
};
13771385

1386+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
13781387
let args = PassAlongPathArgs::new(&nodes[0], expected_route[0], amt_msat, payment_hash, ev)
13791388
.without_claimable_event()
1380-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1389+
.with_dummy_tlvs(&dummy_tlvs);
13811390
do_pass_along_path(args);
13821391

13831392
let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
13841393
let args = PassAlongPathArgs::new(&nodes[0], expected_route[1], amt_msat, payment_hash, ev)
1385-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1394+
.with_dummy_tlvs(&dummy_tlvs);
13861395
let claimable_ev = do_pass_along_path(args).unwrap();
13871396
let keysend_preimage = match claimable_ev {
13881397
Event::PaymentClaimable {
@@ -1391,11 +1400,10 @@ fn async_receive_mpp() {
13911400
} => payment_preimage.unwrap(),
13921401
_ => panic!(),
13931402
};
1394-
claim_payment_along_route(ClaimAlongRouteArgs::new(
1395-
&nodes[0],
1396-
expected_route,
1397-
keysend_preimage,
1398-
));
1403+
claim_payment_along_route(
1404+
ClaimAlongRouteArgs::new(&nodes[0], expected_route, keysend_preimage)
1405+
.with_dummy_tlvs(&dummy_tlvs),
1406+
);
13991407
}
14001408

14011409
#[test]
@@ -1498,10 +1506,11 @@ fn amount_doesnt_match_invreq() {
14981506
let payment_hash = extract_payment_hash(&ev);
14991507

15001508
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[3]]];
1509+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
15011510
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
15021511
.without_claimable_event()
15031512
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash })
1504-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1513+
.with_dummy_tlvs(&dummy_tlvs);
15051514
do_pass_along_path(args);
15061515

15071516
// Modify the invoice request stored in our outbounds to be the correct one, to make sure the
@@ -1526,10 +1535,12 @@ fn amount_doesnt_match_invreq() {
15261535
check_added_monitors(&nodes[0], 1);
15271536
let route: &[&[&Node]] = &[&[&nodes[2], &nodes[3]]];
15281537
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
1529-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1538+
.with_dummy_tlvs(&dummy_tlvs);
15301539
let claimable_ev = do_pass_along_path(args).unwrap();
15311540
let keysend_preimage = extract_payment_preimage(&claimable_ev);
1532-
claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage));
1541+
claim_payment_along_route(
1542+
ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
1543+
);
15331544
}
15341545

15351546
#[test]
@@ -1717,8 +1728,9 @@ fn invalid_async_receive_with_retry<F1, F2>(
17171728
let payment_hash = extract_payment_hash(&ev);
17181729

17191730
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
1731+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
17201732
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
1721-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1733+
.with_dummy_tlvs(&dummy_tlvs);
17221734
do_pass_along_path(args);
17231735

17241736
// Fail the HTLC backwards to enable us to more easily modify the now-Retryable outbound to test
@@ -1746,7 +1758,7 @@ fn invalid_async_receive_with_retry<F1, F2>(
17461758
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
17471759
.without_claimable_event()
17481760
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash })
1749-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1761+
.with_dummy_tlvs(&dummy_tlvs);
17501762
do_pass_along_path(args);
17511763
fail_blinded_htlc_backwards(payment_hash, 1, &[&nodes[0], &nodes[1], &nodes[2]], true);
17521764

@@ -1759,10 +1771,12 @@ fn invalid_async_receive_with_retry<F1, F2>(
17591771
check_added_monitors(&nodes[0], 1);
17601772
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
17611773
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
1762-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1774+
.with_dummy_tlvs(&dummy_tlvs);
17631775
let claimable_ev = do_pass_along_path(args).unwrap();
17641776
let keysend_preimage = extract_payment_preimage(&claimable_ev);
1765-
claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage));
1777+
claim_payment_along_route(
1778+
ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
1779+
);
17661780
}
17671781

17681782
#[cfg_attr(feature = "std", ignore)]
@@ -1933,10 +1947,11 @@ fn expired_static_invoice_payment_path() {
19331947
check_added_monitors(&nodes[0], 1);
19341948

19351949
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
1950+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
19361951
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
19371952
.without_claimable_event()
19381953
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash })
1939-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1954+
.with_dummy_tlvs(&dummy_tlvs);
19401955
do_pass_along_path(args);
19411956
fail_blinded_htlc_backwards(payment_hash, 1, &[&nodes[0], &nodes[1], &nodes[2]], false);
19421957
nodes[2].logger.assert_log_contains(
@@ -2379,11 +2394,14 @@ fn refresh_static_invoices_for_used_offers() {
23792394
check_added_monitors(&sender, 1);
23802395

23812396
let route: &[&[&Node]] = &[&[server, recipient]];
2397+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
23822398
let args = PassAlongPathArgs::new(sender, route[0], amt_msat, payment_hash, ev)
2383-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
2399+
.with_dummy_tlvs(&dummy_tlvs);
23842400
let claimable_ev = do_pass_along_path(args).unwrap();
23852401
let keysend_preimage = extract_payment_preimage(&claimable_ev);
2386-
let res = claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
2402+
let res = claim_payment_along_route(
2403+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
2404+
);
23872405
assert_eq!(res.0, Some(PaidBolt12Invoice::StaticInvoice(updated_invoice)));
23882406
}
23892407

@@ -2714,11 +2732,14 @@ fn invoice_server_is_not_channel_peer() {
27142732
check_added_monitors(&sender, 1);
27152733

27162734
let route: &[&[&Node]] = &[&[forwarding_node, recipient]];
2735+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
27172736
let args = PassAlongPathArgs::new(sender, route[0], amt_msat, payment_hash, ev)
2718-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
2737+
.with_dummy_tlvs(&dummy_tlvs);
27192738
let claimable_ev = do_pass_along_path(args).unwrap();
27202739
let keysend_preimage = extract_payment_preimage(&claimable_ev);
2721-
let res = claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
2740+
let res = claim_payment_along_route(
2741+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
2742+
);
27222743
assert_eq!(res.0, Some(PaidBolt12Invoice::StaticInvoice(invoice)));
27232744
}
27242745

@@ -2954,14 +2975,16 @@ fn async_payment_e2e() {
29542975
check_added_monitors(&sender_lsp, 1);
29552976

29562977
let path: &[&Node] = &[invoice_server, recipient];
2978+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
29572979
let args = PassAlongPathArgs::new(sender_lsp, path, amt_msat, payment_hash, ev)
2958-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
2980+
.with_dummy_tlvs(&dummy_tlvs);
29592981
let claimable_ev = do_pass_along_path(args).unwrap();
29602982

29612983
let route: &[&[&Node]] = &[&[sender_lsp, invoice_server, recipient]];
29622984
let keysend_preimage = extract_payment_preimage(&claimable_ev);
2963-
let (res, _) =
2964-
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
2985+
let (res, _) = claim_payment_along_route(
2986+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
2987+
);
29652988
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));
29662989
}
29672990

@@ -3191,14 +3214,16 @@ fn intercepted_hold_htlc() {
31913214
check_added_monitors(&lsp, 1);
31923215

31933216
let path: &[&Node] = &[recipient];
3194-
let args = PassAlongPathArgs::new(lsp, path, amt_msat, payment_hash, ev)
3195-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
3217+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
3218+
let args =
3219+
PassAlongPathArgs::new(lsp, path, amt_msat, payment_hash, ev).with_dummy_tlvs(&dummy_tlvs);
31963220
let claimable_ev = do_pass_along_path(args).unwrap();
31973221

31983222
let route: &[&[&Node]] = &[&[lsp, recipient]];
31993223
let keysend_preimage = extract_payment_preimage(&claimable_ev);
3200-
let (res, _) =
3201-
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
3224+
let (res, _) = claim_payment_along_route(
3225+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
3226+
);
32023227
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));
32033228
}
32043229

@@ -3294,9 +3319,10 @@ fn async_payment_mpp() {
32943319
let mut events = lsp_a.node.get_and_clear_pending_msg_events();
32953320
assert_eq!(events.len(), 1);
32963321
let ev = remove_first_msg_event_to_node(&recipient.node.get_our_node_id(), &mut events);
3322+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
32973323
let args = PassAlongPathArgs::new(lsp_a, expected_path, amt_msat, payment_hash, ev)
32983324
.without_claimable_event()
3299-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
3325+
.with_dummy_tlvs(&dummy_tlvs);
33003326
do_pass_along_path(args);
33013327

33023328
lsp_b.node.process_pending_htlc_forwards();
@@ -3305,7 +3331,7 @@ fn async_payment_mpp() {
33053331
assert_eq!(events.len(), 1);
33063332
let ev = remove_first_msg_event_to_node(&recipient.node.get_our_node_id(), &mut events);
33073333
let args = PassAlongPathArgs::new(lsp_b, expected_path, amt_msat, payment_hash, ev)
3308-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
3334+
.with_dummy_tlvs(&dummy_tlvs);
33093335
let claimable_ev = do_pass_along_path(args).unwrap();
33103336

33113337
let keysend_preimage = match claimable_ev {
@@ -3317,7 +3343,10 @@ fn async_payment_mpp() {
33173343
};
33183344

33193345
let expected_route: &[&[&Node]] = &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]];
3320-
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, expected_route, keysend_preimage));
3346+
claim_payment_along_route(
3347+
ClaimAlongRouteArgs::new(sender, expected_route, keysend_preimage)
3348+
.with_per_path_dummy_tlvs(&vec![dummy_tlvs.to_vec(); expected_route.len()]),
3349+
);
33213350
}
33223351

33233352
#[test]
@@ -3441,13 +3470,15 @@ fn release_htlc_races_htlc_onion_decode() {
34413470
check_added_monitors(&sender_lsp, 1);
34423471

34433472
let path: &[&Node] = &[invoice_server, recipient];
3473+
let dummy_tlvs = [DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS];
34443474
let args = PassAlongPathArgs::new(sender_lsp, path, amt_msat, payment_hash, ev)
3445-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
3475+
.with_dummy_tlvs(&dummy_tlvs);
34463476
let claimable_ev = do_pass_along_path(args).unwrap();
34473477

34483478
let route: &[&[&Node]] = &[&[sender_lsp, invoice_server, recipient]];
34493479
let keysend_preimage = extract_payment_preimage(&claimable_ev);
3450-
let (res, _) =
3451-
claim_payment_along_route(ClaimAlongRouteArgs::new(sender, route, keysend_preimage));
3480+
let (res, _) = claim_payment_along_route(
3481+
ClaimAlongRouteArgs::new(sender, route, keysend_preimage).with_dummy_tlvs(&dummy_tlvs),
3482+
);
34523483
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));
34533484
}

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,10 @@ fn one_hop_blinded_path_with_dummy_hops() {
261261
.with_payment_secret(payment_secret);
262262

263263
do_pass_along_path(args);
264-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
264+
let path: &[&[&Node<'_, '_, '_>]] = &[&[&nodes[1]]];
265+
let claim_args =
266+
ClaimAlongRouteArgs::new(&nodes[0], path, payment_preimage).with_dummy_tlvs(&dummy_tlvs);
267+
claim_payment_along_route(claim_args);
265268
}
266269

267270
#[test]

0 commit comments

Comments
 (0)