Skip to content

Commit c6d2a54

Browse files
Payment retries: copy tests from InvoicePayer
As part of migrating payment retries from InvoicePayer to ChannelManager, several tests don't need a rewrite and can be pretty much copied and pasted.
1 parent 9756c5d commit c6d2a54

File tree

1 file changed

+325
-0
lines changed

1 file changed

+325
-0
lines changed

lightning/src/ln/payment_tests.rs

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,3 +2047,328 @@ fn fails_paying_after_rejected_by_payee() {
20472047
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::FailedPayment { payment_hash }]);
20482048
pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, payment_hash);
20492049
}
2050+
2051+
#[test]
2052+
fn retry_multi_path_single_failed_payment() {
2053+
// Tests that we can/will retry after a single path of an MPP payment failed immediately
2054+
let chanmon_cfgs = create_chanmon_cfgs(2);
2055+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2056+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
2057+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2058+
2059+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
2060+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
2061+
let chans = nodes[0].node.list_usable_channels();
2062+
let mut route = Route {
2063+
paths: vec![
2064+
vec![RouteHop {
2065+
pubkey: nodes[1].node.get_our_node_id(),
2066+
node_features: channelmanager::provided_node_features(),
2067+
short_channel_id: chans[0].short_channel_id.unwrap(),
2068+
channel_features: channelmanager::provided_channel_features(),
2069+
fee_msat: 10_000,
2070+
cltv_expiry_delta: 100,
2071+
}],
2072+
vec![RouteHop {
2073+
pubkey: nodes[1].node.get_our_node_id(),
2074+
node_features: channelmanager::provided_node_features(),
2075+
short_channel_id: chans[1].short_channel_id.unwrap(),
2076+
channel_features: channelmanager::provided_channel_features(),
2077+
fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
2078+
cltv_expiry_delta: 100,
2079+
}],
2080+
],
2081+
payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())),
2082+
};
2083+
nodes[0].router.expect_find_route(Ok(route.clone()));
2084+
// On retry, split the payment across both channels.
2085+
route.paths[0][0].fee_msat = 50_000_001;
2086+
route.paths[1][0].fee_msat = 50_000_000;
2087+
nodes[0].router.expect_find_route(Ok(route.clone()));
2088+
2089+
let amt_msat = 100_010_000;
2090+
let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
2091+
#[cfg(feature = "std")]
2092+
let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
2093+
#[cfg(not(feature = "std"))]
2094+
let payment_expiry_secs = 60 * 60;
2095+
let mut invoice_features = InvoiceFeatures::empty();
2096+
invoice_features.set_variable_length_onion_required();
2097+
invoice_features.set_payment_secret_required();
2098+
invoice_features.set_basic_mpp_optional();
2099+
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
2100+
.with_expiry_time(payment_expiry_secs as u64)
2101+
.with_features(invoice_features);
2102+
let route_params = RouteParameters {
2103+
payment_params,
2104+
final_value_msat: amt_msat,
2105+
final_cltv_expiry_delta: TEST_FINAL_CLTV,
2106+
};
2107+
2108+
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
2109+
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
2110+
assert_eq!(htlc_msgs.len(), 2);
2111+
check_added_monitors!(nodes[0], 2);
2112+
}
2113+
2114+
#[test]
2115+
fn immediate_retry_on_failure() {
2116+
// Tests that we can/will retry immediately after a failure
2117+
let chanmon_cfgs = create_chanmon_cfgs(2);
2118+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2119+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
2120+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2121+
2122+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
2123+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
2124+
let chans = nodes[0].node.list_usable_channels();
2125+
let mut route = Route {
2126+
paths: vec![
2127+
vec![RouteHop {
2128+
pubkey: nodes[1].node.get_our_node_id(),
2129+
node_features: channelmanager::provided_node_features(),
2130+
short_channel_id: chans[0].short_channel_id.unwrap(),
2131+
channel_features: channelmanager::provided_channel_features(),
2132+
fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
2133+
cltv_expiry_delta: 100,
2134+
}],
2135+
],
2136+
payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())),
2137+
};
2138+
nodes[0].router.expect_find_route(Ok(route.clone()));
2139+
// On retry, split the payment across both channels.
2140+
route.paths.push(route.paths[0].clone());
2141+
route.paths[0][0].short_channel_id = chans[1].short_channel_id.unwrap();
2142+
route.paths[0][0].fee_msat = 50_000_000;
2143+
route.paths[1][0].fee_msat = 50_000_001;
2144+
nodes[0].router.expect_find_route(Ok(route.clone()));
2145+
2146+
let amt_msat = 100_010_000;
2147+
let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
2148+
#[cfg(feature = "std")]
2149+
let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
2150+
#[cfg(not(feature = "std"))]
2151+
let payment_expiry_secs = 60 * 60;
2152+
let mut invoice_features = InvoiceFeatures::empty();
2153+
invoice_features.set_variable_length_onion_required();
2154+
invoice_features.set_payment_secret_required();
2155+
invoice_features.set_basic_mpp_optional();
2156+
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
2157+
.with_expiry_time(payment_expiry_secs as u64)
2158+
.with_features(invoice_features);
2159+
let route_params = RouteParameters {
2160+
payment_params,
2161+
final_value_msat: amt_msat,
2162+
final_cltv_expiry_delta: TEST_FINAL_CLTV,
2163+
};
2164+
2165+
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
2166+
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
2167+
assert_eq!(htlc_msgs.len(), 2);
2168+
check_added_monitors!(nodes[0], 2);
2169+
}
2170+
2171+
#[test]
2172+
fn no_extra_retries_on_back_to_back_fail() {
2173+
// In a previous release, we had a race where we may exceed the payment retry count if we
2174+
// get two failures in a row with the second having `all_paths_failed` set.
2175+
// Generally, when we give up trying to retry a payment, we don't know for sure what the
2176+
// current state of the ChannelManager event queue is. Specifically, we cannot be sure that
2177+
// there are not multiple additional `PaymentPathFailed` or even `PaymentSent` events
2178+
// pending which we will see later. Thus, when we previously removed the retry tracking map
2179+
// entry after a `all_paths_failed` `PaymentPathFailed` event, we may have dropped the
2180+
// retry entry even though more events for the same payment were still pending. This led to
2181+
// us retrying a payment again even though we'd already given up on it.
2182+
//
2183+
// We now have a separate event - `PaymentFailed` which indicates no HTLCs remain and which
2184+
// is used to remove the payment retry counter entries instead. This tests for the specific
2185+
// excess-retry case while also testing `PaymentFailed` generation.
2186+
2187+
let chanmon_cfgs = create_chanmon_cfgs(3);
2188+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
2189+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
2190+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
2191+
2192+
let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
2193+
let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
2194+
2195+
let mut route = Route {
2196+
paths: vec![
2197+
vec![RouteHop {
2198+
pubkey: nodes[1].node.get_our_node_id(),
2199+
node_features: channelmanager::provided_node_features(),
2200+
short_channel_id: chan_1_scid,
2201+
channel_features: channelmanager::provided_channel_features(),
2202+
fee_msat: 0,
2203+
cltv_expiry_delta: 100,
2204+
}, RouteHop {
2205+
pubkey: nodes[2].node.get_our_node_id(),
2206+
node_features: channelmanager::provided_node_features(),
2207+
short_channel_id: chan_2_scid,
2208+
channel_features: channelmanager::provided_channel_features(),
2209+
fee_msat: 100_000_000,
2210+
cltv_expiry_delta: 100,
2211+
}],
2212+
vec![RouteHop {
2213+
pubkey: nodes[1].node.get_our_node_id(),
2214+
node_features: channelmanager::provided_node_features(),
2215+
short_channel_id: chan_1_scid,
2216+
channel_features: channelmanager::provided_channel_features(),
2217+
fee_msat: 0,
2218+
cltv_expiry_delta: 100,
2219+
}, RouteHop {
2220+
pubkey: nodes[2].node.get_our_node_id(),
2221+
node_features: channelmanager::provided_node_features(),
2222+
short_channel_id: chan_2_scid,
2223+
channel_features: channelmanager::provided_channel_features(),
2224+
fee_msat: 100_000_000,
2225+
cltv_expiry_delta: 100,
2226+
}]
2227+
],
2228+
payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id())),
2229+
};
2230+
nodes[0].router.expect_find_route(Ok(route.clone()));
2231+
// On retry, we'll only be asked for one path
2232+
route.paths.remove(1);
2233+
nodes[0].router.expect_find_route(Ok(route.clone()));
2234+
2235+
let amt_msat = 100_010_000;
2236+
let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
2237+
#[cfg(feature = "std")]
2238+
let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
2239+
#[cfg(not(feature = "std"))]
2240+
let payment_expiry_secs = 60 * 60;
2241+
let mut invoice_features = InvoiceFeatures::empty();
2242+
invoice_features.set_variable_length_onion_required();
2243+
invoice_features.set_payment_secret_required();
2244+
invoice_features.set_basic_mpp_optional();
2245+
let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
2246+
.with_expiry_time(payment_expiry_secs as u64)
2247+
.with_features(invoice_features);
2248+
let route_params = RouteParameters {
2249+
payment_params,
2250+
final_value_msat: amt_msat,
2251+
final_cltv_expiry_delta: TEST_FINAL_CLTV,
2252+
};
2253+
2254+
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
2255+
let htlc_updates = SendEvent::from_node(&nodes[0]);
2256+
check_added_monitors!(nodes[0], 1);
2257+
assert_eq!(htlc_updates.msgs.len(), 1);
2258+
2259+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &htlc_updates.msgs[0]);
2260+
nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &htlc_updates.commitment_msg);
2261+
check_added_monitors!(nodes[1], 1);
2262+
let (bs_first_raa, bs_first_cs) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2263+
2264+
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_first_raa);
2265+
check_added_monitors!(nodes[0], 1);
2266+
let second_htlc_updates = SendEvent::from_node(&nodes[0]);
2267+
2268+
nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_first_cs);
2269+
check_added_monitors!(nodes[0], 1);
2270+
let as_first_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
2271+
2272+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &second_htlc_updates.msgs[0]);
2273+
nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &second_htlc_updates.commitment_msg);
2274+
check_added_monitors!(nodes[1], 1);
2275+
let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
2276+
2277+
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_first_raa);
2278+
check_added_monitors!(nodes[1], 1);
2279+
let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2280+
2281+
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_raa);
2282+
check_added_monitors!(nodes[0], 1);
2283+
2284+
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
2285+
nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_fail_update.commitment_signed);
2286+
check_added_monitors!(nodes[0], 1);
2287+
let (as_second_raa, as_third_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
2288+
2289+
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_raa);
2290+
check_added_monitors!(nodes[1], 1);
2291+
let bs_second_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2292+
2293+
nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_third_cs);
2294+
check_added_monitors!(nodes[1], 1);
2295+
let bs_third_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
2296+
2297+
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.update_fail_htlcs[0]);
2298+
nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_fail_update.commitment_signed);
2299+
check_added_monitors!(nodes[0], 1);
2300+
2301+
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_third_raa);
2302+
check_added_monitors!(nodes[0], 1);
2303+
let (as_third_raa, as_fourth_cs) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
2304+
2305+
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_third_raa);
2306+
check_added_monitors!(nodes[1], 1);
2307+
nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_fourth_cs);
2308+
check_added_monitors!(nodes[1], 1);
2309+
let bs_fourth_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
2310+
2311+
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_fourth_raa);
2312+
check_added_monitors!(nodes[0], 1);
2313+
2314+
// At this point A has sent two HTLCs which both failed due to lack of fee. It now has two
2315+
// pending `PaymentPathFailed` events, one with `all_paths_failed` unset, and the second
2316+
// with it set. The first event will use up the only retry we are allowed, with the second
2317+
// `PaymentPathFailed` being passed up to the user (us, in this case). Previously, we'd
2318+
// treated this as "HTLC complete" and dropped the retry counter, causing us to retry again
2319+
// if the final HTLC failed.
2320+
let mut events = nodes[0].node.get_and_clear_pending_events();
2321+
assert_eq!(events.len(), 4);
2322+
match events[0] {
2323+
Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, .. } => {
2324+
assert_eq!(payment_hash, ev_payment_hash);
2325+
assert_eq!(payment_failed_permanently, false);
2326+
},
2327+
_ => panic!("Unexpected event"),
2328+
}
2329+
match events[1] {
2330+
Event::PendingHTLCsForwardable { .. } => {},
2331+
_ => panic!("Unexpected event"),
2332+
}
2333+
match events[2] {
2334+
Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, .. } => {
2335+
assert_eq!(payment_hash, ev_payment_hash);
2336+
assert_eq!(payment_failed_permanently, false);
2337+
},
2338+
_ => panic!("Unexpected event"),
2339+
}
2340+
match events[3] {
2341+
Event::PendingHTLCsForwardable { .. } => {},
2342+
_ => panic!("Unexpected event"),
2343+
}
2344+
2345+
nodes[0].node.process_pending_htlc_forwards();
2346+
let retry_htlc_updates = SendEvent::from_node(&nodes[0]);
2347+
check_added_monitors!(nodes[0], 1);
2348+
2349+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &retry_htlc_updates.msgs[0]);
2350+
commitment_signed_dance!(nodes[1], nodes[0], &retry_htlc_updates.commitment_msg, false, true);
2351+
let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2352+
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_update.update_fail_htlcs[0]);
2353+
commitment_signed_dance!(nodes[0], nodes[1], &bs_fail_update.commitment_signed, false, true);
2354+
2355+
let mut events = nodes[0].node.get_and_clear_pending_events();
2356+
assert_eq!(events.len(), 1);
2357+
match events[0] {
2358+
Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, .. } => {
2359+
assert_eq!(payment_hash, ev_payment_hash);
2360+
assert_eq!(payment_failed_permanently, false);
2361+
},
2362+
_ => panic!("Unexpected event"),
2363+
}
2364+
nodes[0].node.abandon_payment(PaymentId(payment_hash.0));
2365+
events = nodes[0].node.get_and_clear_pending_events();
2366+
assert_eq!(events.len(), 1);
2367+
match events[0] {
2368+
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
2369+
assert_eq!(payment_hash, *ev_payment_hash);
2370+
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
2371+
},
2372+
_ => panic!("Unexpected event"),
2373+
}
2374+
}

0 commit comments

Comments
 (0)