unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)),
true, APIError::ChannelUnavailable { ref err },
- assert_eq!(err, "Peer for first hop currently disconnected/pending monitor update!"));
+ assert_eq!(err, "Peer for first hop currently disconnected"));
assert!(!nodes[0].node.has_pending_payments());
}
assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
- nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }).unwrap();
+ nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
// Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
// error, as the channel has hit the chain.
- nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }).unwrap();
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
let as_err = nodes[0].node.get_and_clear_pending_msg_events();
assert!(nodes[0].node.has_pending_payments());
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
- nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }).unwrap();
+ nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
// Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
// error, as the channel has hit the chain.
- nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }).unwrap();
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).unwrap();
let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
let as_err = nodes[0].node.get_and_clear_pending_msg_events();
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,
+ network_update: None, all_paths_failed: false, short_channel_id: Some(expected_scid), .. } => {
+ assert_eq!(payment_hash, ev_payment_hash);
+ assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+ },
+ _ => 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,
+ network_update: None, all_paths_failed: false, short_channel_id: Some(expected_scid), .. } => {
+ assert_eq!(payment_hash, ev_payment_hash);
+ assert_eq!(expected_scid, route.paths[1][0].short_channel_id);
+ },
+ _ => 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);