use crate::chain::keysinterface::EntropySource;
use crate::chain::transaction::OutPoint;
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
-use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS};
+use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails};
use crate::ln::features::InvoiceFeatures;
use crate::ln::msgs;
use crate::ln::msgs::ChannelMessageHandler;
assert_eq!(events.len(), 2);
// Pass half of the payment along the success path.
- let (success_path_msgs, mut events) = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &events);
+ let success_path_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 2_000_000, payment_hash, Some(payment_secret), success_path_msgs, false, None);
// Add the HTLC along the first hop.
- let (fail_path_msgs_1, _events) = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &events);
+ let fail_path_msgs_1 = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
let (update_add, commitment_signed) = match fail_path_msgs_1 {
MessageSendEvent::UpdateHTLCs { node_id: _, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
assert_eq!(update_add_htlcs.len(), 1);
assert_eq!(events.len(), 2);
// Pass half of the payment along the first path.
- let (node_1_msgs, mut events) = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &events);
+ let node_1_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 200_000, payment_hash, Some(payment_secret), node_1_msgs, false, None);
if send_partial_mpp {
expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
} else {
// Pass half of the payment along the second path.
- let (node_2_msgs, _events) = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &events);
+ let node_2_msgs = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), node_2_msgs, true, None);
// Even after MPP_TIMEOUT_TICKS we should not timeout the MPP if we have all the parts
let (_, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 1, 2);
// Send and claim the payment. Inflight HTLCs should be empty.
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 500000);
+ let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 500000);
+ nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
+ check_added_monitors!(nodes[0], 1);
+ pass_along_route(&nodes[0], &[&vec!(&nodes[1], &nodes[2])[..]], 500000, payment_hash, payment_secret);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], payment_preimage);
{
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
assert_eq!(chan_1_used_liquidity, None);
assert_eq!(chan_2_used_liquidity, None);
}
+ let pending_payments = nodes[0].node.list_recent_payments();
+ assert_eq!(pending_payments.len(), 1);
+ assert_eq!(pending_payments[0], RecentPaymentDetails::Fulfilled { payment_hash: Some(payment_hash) });
+
+ // Remove fulfilled payment
+ for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
+ nodes[0].node.timer_tick_occurred();
+ }
// Send the payment, but do not claim it. Our inflight HTLCs should contain the pending payment.
- let (payment_preimage, _, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 500000);
+ let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 500000);
{
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
assert_eq!(chan_1_used_liquidity, Some(501000));
assert_eq!(chan_2_used_liquidity, Some(500000));
}
+ let pending_payments = nodes[0].node.list_recent_payments();
+ assert_eq!(pending_payments.len(), 1);
+ assert_eq!(pending_payments[0], RecentPaymentDetails::Pending { payment_hash, total_msat: 500000 });
// Now, let's claim the payment. This should result in the used liquidity to return `None`.
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
+
+ // Remove fulfilled payment
+ for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS {
+ nodes[0].node.timer_tick_occurred();
+ }
+
{
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
assert_eq!(chan_1_used_liquidity, None);
assert_eq!(chan_2_used_liquidity, None);
}
+
+ let pending_payments = nodes[0].node.list_recent_payments();
+ assert_eq!(pending_payments.len(), 0);
}
#[test]