Skip to content

Commit cd5709f

Browse files
f MPP test
1 parent ae76024 commit cd5709f

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

lightning/src/ln/offers_tests.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,13 +2259,13 @@ fn fails_paying_invoice_with_unknown_required_features() {
22592259
fn no_double_pay_with_stale_channelmanager() {
22602260
// This tests the following bug:
22612261
// - An outbound payment is AwaitingInvoice
2262-
// - We receive an invoice and lock the HTLCs into the relevant ChannelMonitor
2263-
// - The monitor is successfully persisted, but the ChannelManager fails to persist, so the
2262+
// - We receive an invoice and lock the HTLCs into the relevant ChannelMonitors
2263+
// - The monitors are successfully persisted, but the ChannelManager fails to persist, so the
22642264
// payment remains AwaitingInvoice
2265-
// - We restart, causing the channel to close due to a stale ChannelManager
2265+
// - We restart, causing the channels to close due to a stale ChannelManager
22662266
// - We receive a duplicate invoice, and attempt to pay it again due to the payment still being
22672267
// AwaitingInvoice in the stale ChannelManager
2268-
// After the fix for this, we will notice that the payment is already locked into the monitor on
2268+
// After the fix for this, we will notice that the payment is already locked into the monitors on
22692269
// startup and transition the incorrectly-AwaitingInvoice payment to Retryable, which prevents
22702270
// double-paying on duplicate invoice receipt.
22712271
let chanmon_cfgs = create_chanmon_cfgs(2);
@@ -2275,15 +2275,17 @@ fn no_double_pay_with_stale_channelmanager() {
22752275
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
22762276
let alice_deserialized;
22772277
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2278-
let chan_id = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000).2;
2278+
let chan_id_0 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000).2;
2279+
let chan_id_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000).2;
22792280

22802281
let alice_id = nodes[0].node.get_our_node_id();
22812282
let bob_id = nodes[1].node.get_our_node_id();
22822283

2284+
let amt_msat = nodes[0].node.list_usable_channels()[0].next_outbound_htlc_limit_msat + 1; // Force MPP
22832285
let offer = nodes[1].node
22842286
.create_offer_builder(None).unwrap()
22852287
.clear_paths()
2286-
.amount_msats(10_000_000)
2288+
.amount_msats(amt_msat)
22872289
.build().unwrap();
22882290
assert_eq!(offer.signing_pubkey(), Some(bob_id));
22892291
assert!(offer.paths().is_empty());
@@ -2300,9 +2302,23 @@ fn no_double_pay_with_stale_channelmanager() {
23002302

23012303
let invoice_om = nodes[1].onion_messenger.next_onion_message_for_peer(alice_id).unwrap();
23022304
nodes[0].onion_messenger.handle_onion_message(bob_id, &invoice_om);
2305+
let payment_hash = extract_invoice(&nodes[0], &invoice_om).0.payment_hash();
2306+
2307+
let expected_route: &[&[&Node]] = &[&[&nodes[1]], &[&nodes[1]]];
2308+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
2309+
assert_eq!(events.len(), 2);
2310+
check_added_monitors!(nodes[0], 2);
2311+
2312+
let ev = remove_first_msg_event_to_node(&bob_id, &mut events);
2313+
let args = PassAlongPathArgs::new(&nodes[0], expected_route[0], amt_msat, payment_hash, ev)
2314+
.without_clearing_recipient_events();
2315+
do_pass_along_path(args);
2316+
2317+
let ev = remove_first_msg_event_to_node(&bob_id, &mut events);
2318+
let args = PassAlongPathArgs::new(&nodes[0], expected_route[0], amt_msat, payment_hash, ev)
2319+
.without_clearing_recipient_events();
2320+
do_pass_along_path(args);
23032321

2304-
let (invoice, _) = extract_invoice(&nodes[0], &invoice_om);
2305-
route_bolt12_payment(&nodes[0], &[&nodes[1]], &invoice);
23062322
expect_recent_payment!(nodes[0], RecentPaymentDetails::Pending, payment_id);
23072323
match get_event!(nodes[1], Event::PaymentClaimable) {
23082324
Event::PaymentClaimable { .. } => {},
@@ -2311,16 +2327,17 @@ fn no_double_pay_with_stale_channelmanager() {
23112327

23122328
// Reload with the stale manager and check that receiving the invoice again won't result in a
23132329
// duplicate payment attempt.
2314-
let monitor = get_monitor!(nodes[0], chan_id).encode();
2315-
reload_node!(nodes[0], &alice_chan_manager_serialized, &[&monitor], persister, chain_monitor, alice_deserialized);
2316-
// The stale manager results in closing the channel.
2317-
check_closed_event!(nodes[0], 1, ClosureReason::OutdatedChannelManager, [bob_id], 10_000_000);
2318-
check_added_monitors!(nodes[0], 1);
2330+
let monitor_0 = get_monitor!(nodes[0], chan_id_0).encode();
2331+
let monitor_1 = get_monitor!(nodes[0], chan_id_1).encode();
2332+
reload_node!(nodes[0], &alice_chan_manager_serialized, &[&monitor_0, &monitor_1], persister, chain_monitor, alice_deserialized);
2333+
// The stale manager results in closing the channels.
2334+
check_closed_event!(nodes[0], 2, ClosureReason::OutdatedChannelManager, [bob_id, bob_id], 10_000_000);
2335+
check_added_monitors!(nodes[0], 2);
23192336

23202337
// Alice receives a duplicate invoice, but the payment should be transitioned to Retryable by now.
23212338
nodes[0].onion_messenger.handle_onion_message(bob_id, &invoice_om);
23222339
// Previously, Alice would've attempted to pay the invoice a 2nd time. In this test case, this 2nd
2323-
// attempt would have resulted in a PaymentFailed event here, since the only channnel between
2340+
// attempt would have resulted in a PaymentFailed event here, since the only channnels between
23242341
// Alice and Bob is closed. Since no 2nd attempt should be made, check that no events are
23252342
// generated in response to the duplicate invoice.
23262343
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());

0 commit comments

Comments
 (0)