use crate::routing::gossip::{EffectiveCapacity, RoutingFees};
use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RouteParameters};
use crate::routing::scoring::ChannelUsage;
-use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider};
+use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure};
use crate::util::test_utils;
use crate::util::errors::APIError;
use crate::util::ser::Writeable;
payment_params: Some(route_params.payment_params.clone()),
};
nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
+ let mut payment_params = route_params.payment_params.clone();
+ payment_params.previously_failed_channels.push(chan_2_id);
nodes[0].router.expect_find_route(RouteParameters {
- payment_params: route_params.payment_params.clone(),
- final_value_msat: amt_msat / 2, final_cltv_expiry_delta: TEST_FINAL_CLTV
+ payment_params, final_value_msat: amt_msat / 2, final_cltv_expiry_delta: TEST_FINAL_CLTV
}, Ok(retry_1_route));
+ let mut payment_params = route_params.payment_params.clone();
+ payment_params.previously_failed_channels.push(chan_3_id);
nodes[0].router.expect_find_route(RouteParameters {
- payment_params: route_params.payment_params.clone(),
- final_value_msat: amt_msat / 4, final_cltv_expiry_delta: TEST_FINAL_CLTV
+ payment_params, final_value_msat: amt_msat / 4, final_cltv_expiry_delta: TEST_FINAL_CLTV
}, Ok(retry_2_route));
// Send a payment that will partially fail on send, then partially fail on retry, then succeed.
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(3)).unwrap();
let closed_chan_events = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(closed_chan_events.len(), 2);
+ assert_eq!(closed_chan_events.len(), 4);
match closed_chan_events[0] {
Event::ChannelClosed { .. } => {},
_ => panic!("Unexpected event"),
}
match closed_chan_events[1] {
+ Event::PaymentPathFailed { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+ match closed_chan_events[2] {
Event::ChannelClosed { .. } => {},
_ => panic!("Unexpected event"),
}
+ match closed_chan_events[3] {
+ Event::PaymentPathFailed { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
// Pass the first part of the payment along the path.
check_added_monitors!(nodes[0], 5); // three outbound channel updates succeeded, two permanently failed
};
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
- let err = nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap_err();
- if let PaymentSendFailure::AllFailedResendSafe(_) = err {
- } else { panic!("Unexpected error"); }
+ nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
assert_eq!(nodes[0].node.get_and_clear_pending_msg_events().len(), 2); // channel close messages
- assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 1); // channel close event
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 3);
+ if let Event::ChannelClosed { .. } = events[0] { } else { panic!(); }
+ if let Event::PaymentPathFailed { .. } = events[1] { } else { panic!(); }
+ if let Event::PaymentFailed { .. } = events[2] { } else { panic!(); }
check_added_monitors!(nodes[0], 2);
}
// On retry, split the payment across both channels.
route.paths[0][0].fee_msat = 50_000_001;
route.paths[1][0].fee_msat = 50_000_000;
+ let mut pay_params = route.payment_params.clone().unwrap();
+ pay_params.previously_failed_channels.push(chans[1].short_channel_id.unwrap());
nodes[0].router.expect_find_route(RouteParameters {
- payment_params: route.payment_params.clone().unwrap(),
+ payment_params: pay_params,
// Note that the second request here requests the amount we originally failed to send,
// not the amount remaining on the full payment, which should be changed.
final_value_msat: 100_000_001, final_cltv_expiry_delta: TEST_FINAL_CLTV
}
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false,
+ failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }},
+ short_channel_id: Some(expected_scid), .. } =>
+ {
+ assert_eq!(payment_hash, ev_payment_hash);
+ assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+ assert!(err_msg.contains("max HTLC"));
+ },
+ _ => panic!("Unexpected event"),
+ }
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(htlc_msgs.len(), 2);
check_added_monitors!(nodes[0], 2);
route.paths[0][0].short_channel_id = chans[1].short_channel_id.unwrap();
route.paths[0][0].fee_msat = 50_000_000;
route.paths[1][0].fee_msat = 50_000_001;
+ let mut pay_params = route_params.payment_params.clone();
+ pay_params.previously_failed_channels.push(chans[0].short_channel_id.unwrap());
nodes[0].router.expect_find_route(RouteParameters {
- payment_params: route_params.payment_params.clone(),
- final_value_msat: amt_msat, final_cltv_expiry_delta: TEST_FINAL_CLTV
+ payment_params: pay_params, final_value_msat: amt_msat,
+ final_cltv_expiry_delta: TEST_FINAL_CLTV
}, Ok(route.clone()));
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false,
+ failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }},
+ short_channel_id: Some(expected_scid), .. } =>
+ {
+ assert_eq!(payment_hash, ev_payment_hash);
+ assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+ assert!(err_msg.contains("max HTLC"));
+ },
+ _ => panic!("Unexpected event"),
+ }
let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(htlc_msgs.len(), 2);
check_added_monitors!(nodes[0], 2);
#[test]
fn no_extra_retries_on_back_to_back_fail() {
// In a previous release, we had a race where we may exceed the payment retry count if we
- // get two failures in a row with the second having `all_paths_failed` set.
+ // get two failures in a row with the second indicating that all paths had failed (this field,
+ // `all_paths_failed`, has since been removed).
// Generally, when we give up trying to retry a payment, we don't know for sure what the
// current state of the ChannelManager event queue is. Specifically, we cannot be sure that
// there are not multiple additional `PaymentPathFailed` or even `PaymentSent` events