diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 22e493ae1c5..94033bc072c 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -1397,7 +1397,9 @@ mod test { let payment_preimage_opt = if user_generated_pmt_hash { None } else { Some(payment_preimage) }; assert_eq!(other_events.borrow().len(), 1); check_payment_claimable(&other_events.borrow()[0], payment_hash, payment_secret, payment_amt, payment_preimage_opt, invoice.recover_payee_pub_key()); - do_claim_payment_along_route(&nodes[0], &[&vec!(&nodes[fwd_idx])[..]], false, payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[fwd_idx]]], payment_preimage) + ); expect_payment_sent(&nodes[0], payment_preimage, None, true, true); } diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index a4bf1501b19..0350f816a48 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -653,6 +653,11 @@ pub enum Event { /// The sender-intended sum total of all the MPP parts. This will be `None` for events /// serialized prior to LDK version 0.0.117. sender_intended_total_msat: Option, + /// The fields in the onion which were received with each HTLC. Only fields which were + /// identical in each HTLC involved in the payment will be included here. + /// + /// Payments received on LDK versions prior to 0.0.124 will have this field unset. + onion_fields: Option, }, /// Indicates that a peer connection with a node is needed in order to send an [`OnionMessage`]. /// @@ -1348,7 +1353,7 @@ impl Writeable for Event { // We never write the OpenChannelRequest events as, upon disconnection, peers // drop any channels which have not yet exchanged funding_signed. }, - &Event::PaymentClaimed { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref htlcs, ref sender_intended_total_msat } => { + &Event::PaymentClaimed { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref htlcs, ref sender_intended_total_msat, ref onion_fields } => { 19u8.write(writer)?; write_tlv_fields!(writer, { (0, payment_hash, required), @@ -1357,6 +1362,7 @@ impl Writeable for Event { (4, amount_msat, required), (5, *htlcs, optional_vec), (7, sender_intended_total_msat, option), + (9, onion_fields, option), }); }, &Event::ProbeSuccessful { ref payment_id, ref payment_hash, ref path } => { @@ -1719,6 +1725,7 @@ impl MaybeReadable for Event { let mut receiver_node_id = None; let mut htlcs: Option> = Some(vec![]); let mut sender_intended_total_msat: Option = None; + let mut onion_fields = None; read_tlv_fields!(reader, { (0, payment_hash, required), (1, receiver_node_id, option), @@ -1726,6 +1733,7 @@ impl MaybeReadable for Event { (4, amount_msat, required), (5, htlcs, optional_vec), (7, sender_intended_total_msat, option), + (9, onion_fields, option), }); Ok(Some(Event::PaymentClaimed { receiver_node_id, @@ -1734,6 +1742,7 @@ impl MaybeReadable for Event { amount_msat, htlcs: htlcs.unwrap_or(vec![]), sender_intended_total_msat, + onion_fields, })) }; f() diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index 4c254628de6..03c0e49fb46 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -180,7 +180,9 @@ fn mpp_to_one_hop_blinded_path() { let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_route[1], amt_msat, payment_hash.clone(), Some(payment_secret), ev.clone(), true, None); - claim_payment_along_route(&nodes[0], expected_route, false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_route, payment_preimage) + ); } #[test] @@ -244,7 +246,9 @@ fn mpp_to_three_hop_blinded_paths() { let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_route[1], amt_msat, payment_hash.clone(), Some(payment_secret), ev.clone(), true, None); - claim_payment_along_route(&nodes[0], expected_route, false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_route, payment_preimage) + ); } enum ForwardCheckFail { @@ -643,7 +647,9 @@ fn do_blinded_intercept_payment(intercept_node_fails: bool) { expect_pending_htlcs_forwardable!(nodes[2]); expect_payment_claimable!(&nodes[2], payment_hash, payment_secret, amt_msat, None, nodes[2].node.get_our_node_id()); - do_claim_payment_along_route(&nodes[0], &vec!(&vec!(&nodes[1], &nodes[2])[..]), false, payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + ); expect_payment_sent(&nodes[0], payment_preimage, Some(Some(1000)), true, true); } @@ -1217,7 +1223,9 @@ fn blinded_keysend() { let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_route[0], amt_msat, payment_hash, Some(payment_secret), ev.clone(), true, Some(keysend_preimage)); - claim_payment_along_route(&nodes[0], expected_route, false, keysend_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_route, keysend_preimage) + ); } #[test] @@ -1268,7 +1276,9 @@ fn blinded_mpp_keysend() { let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_route[1], amt_msat, payment_hash.clone(), Some(payment_secret), ev.clone(), true, Some(keysend_preimage)); - claim_payment_along_route(&nodes[0], expected_route, false, keysend_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_route, keysend_preimage) + ); } #[test] @@ -1316,5 +1326,8 @@ fn custom_tlvs_to_blinded_path() { .with_payment_secret(payment_secret) .with_custom_tlvs(recipient_onion_fields.custom_tlvs.clone()); do_pass_along_path(args); - claim_payment(&nodes[0], &[&nodes[1]], payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], payment_preimage) + .with_custom_tlvs(recipient_onion_fields.custom_tlvs.clone()) + ); } diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 7d332f2ad78..5e9ce30376b 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -2025,7 +2025,9 @@ fn test_path_paused_mpp() { assert_eq!(events.len(), 1); pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), true, None); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], payment_preimage) + ); } #[test] diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index f2b3bf15d39..1d5191b8007 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -680,6 +680,7 @@ struct ClaimingPayment { receiver_node_id: PublicKey, htlcs: Vec, sender_intended_value: Option, + onion_fields: Option, } impl_writeable_tlv_based!(ClaimingPayment, { (0, amount_msat, required), @@ -687,6 +688,7 @@ impl_writeable_tlv_based!(ClaimingPayment, { (4, receiver_node_id, required), (5, htlcs, optional_vec), (7, sender_intended_value, option), + (9, onion_fields, option), }); struct ClaimablePayment { @@ -6324,19 +6326,27 @@ where } } - let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(); - let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat); - let dup_purpose = claimable_payments.pending_claiming_payments.insert(payment_hash, - ClaimingPayment { amount_msat: payment.htlcs.iter().map(|source| source.value).sum(), - payment_purpose: payment.purpose, receiver_node_id, htlcs, sender_intended_value - }); - if dup_purpose.is_some() { - debug_assert!(false, "Shouldn't get a duplicate pending claim event ever"); - log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug", - &payment_hash); - } + let claiming_payment = claimable_payments.pending_claiming_payments + .entry(payment_hash) + .and_modify(|_| { + debug_assert!(false, "Shouldn't get a duplicate pending claim event ever"); + log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug", + &payment_hash); + }) + .or_insert_with(|| { + let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(); + let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat); + ClaimingPayment { + amount_msat: payment.htlcs.iter().map(|source| source.value).sum(), + payment_purpose: payment.purpose, + receiver_node_id, + htlcs, + sender_intended_value, + onion_fields: payment.onion_fields, + } + }); - if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = payment.onion_fields { + if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = claiming_payment.onion_fields { if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) { log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}", &payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0))); @@ -6743,6 +6753,7 @@ where receiver_node_id, htlcs, sender_intended_value: sender_intended_total_msat, + onion_fields, }) = payment { self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed { payment_hash, @@ -6751,6 +6762,7 @@ where receiver_node_id: Some(receiver_node_id), htlcs, sender_intended_total_msat, + onion_fields, }, None)); } }, @@ -12261,6 +12273,7 @@ where amount_msat: claimable_amt_msat, htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(), sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat), + onion_fields: payment.onion_fields, }, None)); } } diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index cbb2b0f2197..b9688d04348 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -2716,18 +2716,12 @@ pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route (our_payment_preimage, our_payment_hash, our_payment_secret, payment_id) } -pub fn do_claim_payment_along_route<'a, 'b, 'c>( - origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, - our_payment_preimage: PaymentPreimage -) -> u64 { - for path in expected_paths.iter() { - assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id()); +pub fn do_claim_payment_along_route(args: ClaimAlongRouteArgs) -> u64 { + for path in args.expected_paths.iter() { + assert_eq!(path.last().unwrap().node.get_our_node_id(), args.expected_paths[0].last().unwrap().node.get_our_node_id()); } - expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage); - pass_claimed_payment_along_route( - ClaimAlongRouteArgs::new(origin_node, expected_paths, our_payment_preimage) - .skip_last(skip_last) - ) + args.expected_paths[0].last().unwrap().node.claim_funds(args.payment_preimage); + pass_claimed_payment_along_route(args) } pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> { @@ -2737,6 +2731,7 @@ pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> { pub expected_min_htlc_overpay: Vec, pub skip_last: bool, pub payment_preimage: PaymentPreimage, + pub custom_tlvs: Vec<(u64, Vec)>, // Allow forwarding nodes to have taken 1 msat more fee than expected based on the downstream // fulfill amount. // @@ -2755,7 +2750,7 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> { Self { origin_node, expected_paths, expected_extra_fees: vec![0; expected_paths.len()], expected_min_htlc_overpay: vec![0; expected_paths.len()], skip_last: false, payment_preimage, - allow_1_msat_fee_overpay: false, + allow_1_msat_fee_overpay: false, custom_tlvs: vec![], } } pub fn skip_last(mut self, skip_last: bool) -> Self { @@ -2774,12 +2769,16 @@ impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> { self.allow_1_msat_fee_overpay = true; self } + pub fn with_custom_tlvs(mut self, custom_tlvs: Vec<(u64, Vec)>) -> Self { + self.custom_tlvs = custom_tlvs; + self + } } -pub fn pass_claimed_payment_along_route<'a, 'b, 'c, 'd>(args: ClaimAlongRouteArgs) -> u64 { +pub fn pass_claimed_payment_along_route(args: ClaimAlongRouteArgs) -> u64 { let ClaimAlongRouteArgs { origin_node, expected_paths, expected_extra_fees, expected_min_htlc_overpay, skip_last, - payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, + payment_preimage: our_payment_preimage, allow_1_msat_fee_overpay, custom_tlvs, } = args; let claim_event = expected_paths[0].last().unwrap().node.get_and_clear_pending_events(); assert_eq!(claim_event.len(), 1); @@ -2793,11 +2792,13 @@ pub fn pass_claimed_payment_along_route<'a, 'b, 'c, 'd>(args: ClaimAlongRouteArg | PaymentPurpose::Bolt12RefundPayment { payment_preimage: Some(preimage), .. }, amount_msat, ref htlcs, + ref onion_fields, .. } => { assert_eq!(preimage, our_payment_preimage); assert_eq!(htlcs.len(), expected_paths.len()); // One per path. assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::(), amount_msat); + assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs); expected_paths.iter().zip(htlcs).for_each(|(path, htlc)| check_claimed_htlc_channel(origin_node, path, htlc)); fwd_amt_msat = amount_msat; }, @@ -2808,11 +2809,13 @@ pub fn pass_claimed_payment_along_route<'a, 'b, 'c, 'd>(args: ClaimAlongRouteArg payment_hash, amount_msat, ref htlcs, + ref onion_fields, .. } => { assert_eq!(&payment_hash.0, &Sha256::hash(&our_payment_preimage.0)[..]); assert_eq!(htlcs.len(), expected_paths.len()); // One per path. assert_eq!(htlcs.iter().map(|h| h.value_msat).sum::(), amount_msat); + assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs); expected_paths.iter().zip(htlcs).for_each(|(path, htlc)| check_claimed_htlc_channel(origin_node, path, htlc)); fwd_amt_msat = amount_msat; } @@ -2956,15 +2959,20 @@ pub fn pass_claimed_payment_along_route<'a, 'b, 'c, 'd>(args: ClaimAlongRouteArg expected_total_fee_msat } -pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage) { - let expected_total_fee_msat = do_claim_payment_along_route(origin_node, expected_paths, skip_last, our_payment_preimage); +pub fn claim_payment_along_route(args: ClaimAlongRouteArgs) { + let origin_node = args.origin_node; + let payment_preimage = args.payment_preimage; + let skip_last = args.skip_last; + let expected_total_fee_msat = do_claim_payment_along_route(args); if !skip_last { - expect_payment_sent!(origin_node, our_payment_preimage, Some(expected_total_fee_msat)); + expect_payment_sent!(origin_node, payment_preimage, Some(expected_total_fee_msat)); } } pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage) { - claim_payment_along_route(origin_node, &[expected_route], false, our_payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(origin_node, &[expected_route], our_payment_preimage) + ); } pub const TEST_FINAL_CLTV: u32 = 70; diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 5b1420e3d6b..c0e9461f1a3 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -3780,7 +3780,10 @@ fn test_simple_peer_disconnect() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id()); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_preimage_3); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage_3) + .skip_last(true) + ); fail_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], true, payment_hash_5); let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]); @@ -8264,7 +8267,9 @@ fn test_onion_value_mpp_set_calculation() { let ev = remove_first_msg_event_to_node(&expected_paths[1][0].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_paths[1], 101_000, our_payment_hash.clone(), Some(our_payment_secret), ev, true, None); - claim_payment_along_route(&nodes[0], expected_paths, false, our_payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_paths, our_payment_preimage) + ); } fn do_test_overshoot_mpp(msat_amounts: &[u64], total_msat: u64) { @@ -8330,7 +8335,9 @@ fn do_test_overshoot_mpp(msat_amounts: &[u64], total_msat: u64) { pass_along_path(&nodes[src_idx], expected_path, amount_received, our_payment_hash.clone(), Some(our_payment_secret), ev, became_claimable_now, None); } - claim_payment_along_route(&nodes[src_idx], &expected_paths, false, our_payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[src_idx], &expected_paths, our_payment_preimage) + ); } #[test] @@ -8362,7 +8369,9 @@ fn test_simple_mpp() { route.paths[1].hops[0].short_channel_id = chan_2_id; route.paths[1].hops[1].short_channel_id = chan_4_id; send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, payment_secret); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], payment_preimage) + ); } #[test] @@ -9806,7 +9815,9 @@ fn test_inconsistent_mpp_params() { assert_eq!(events.len(), 1); pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 15_000_000, our_payment_hash, Some(our_payment_secret), events.pop().unwrap(), true, None); - do_claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, our_payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], our_payment_preimage) + ); expect_payment_sent(&nodes[0], our_payment_preimage, Some(None), true, true); } diff --git a/lightning/src/ln/max_payment_path_len_tests.rs b/lightning/src/ln/max_payment_path_len_tests.rs index 36fe098b9ee..7bd605c9ddf 100644 --- a/lightning/src/ln/max_payment_path_len_tests.rs +++ b/lightning/src/ln/max_payment_path_len_tests.rs @@ -84,7 +84,9 @@ fn large_payment_metadata() { .with_payment_secret(payment_secret) .with_payment_metadata(payment_metadata.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[0], &[&[&nodes[1]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], payment_preimage) + ); // Check that the payment parameter for max path length will prevent us from routing past our // next-hop peer given the payment_metadata size. @@ -133,7 +135,9 @@ fn large_payment_metadata() { .with_payment_secret(payment_secret_2) .with_payment_metadata(recipient_onion_allows_2_hops.payment_metadata.unwrap()); do_pass_along_path(args); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage_2); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage_2) + ); } #[test] @@ -201,7 +205,10 @@ fn one_hop_blinded_path_with_custom_tlv() { .with_payment_secret(payment_secret) .with_custom_tlvs(recipient_onion_max_custom_tlv_size.custom_tlvs.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[1], &[&[&nodes[2]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[1], &[&[&nodes[2]]], payment_preimage) + .with_custom_tlvs(recipient_onion_max_custom_tlv_size.custom_tlvs.clone()) + ); // If 1 byte is added to the custom TLV value, we'll fail to send prior to pathfinding. let mut recipient_onion_too_large_custom_tlv = recipient_onion_max_custom_tlv_size.clone(); @@ -226,9 +233,12 @@ fn one_hop_blinded_path_with_custom_tlv() { let path = &[&nodes[1], &nodes[2]]; let args = PassAlongPathArgs::new(&nodes[0], path, amt_msat, payment_hash, events.pop().unwrap()) .with_payment_secret(payment_secret) - .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs); + .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs) + ); } #[test] @@ -283,7 +293,10 @@ fn blinded_path_with_custom_tlv() { .with_payment_secret(payment_secret) .with_custom_tlvs(recipient_onion_max_custom_tlv_size.custom_tlvs.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[1], &[&[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[1], &[&[&nodes[2], &nodes[3]]], payment_preimage) + .with_custom_tlvs(recipient_onion_max_custom_tlv_size.custom_tlvs.clone()) + ); // If 1 byte is added to the custom TLV value, we'll fail to send prior to pathfinding. let mut recipient_onion_too_large_custom_tlv = recipient_onion_max_custom_tlv_size.clone(); @@ -320,7 +333,10 @@ fn blinded_path_with_custom_tlv() { let path = &[&nodes[1], &nodes[2], &nodes[3]]; let args = PassAlongPathArgs::new(&nodes[0], path, amt_msat, payment_hash, events.pop().unwrap()) .with_payment_secret(payment_secret) - .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs); + .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2], &nodes[3]]], payment_preimage) + .with_custom_tlvs(recipient_onion_allows_2_hops.custom_tlvs) + ); } diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 761d4b5316c..90964a006ba 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -2896,7 +2896,9 @@ fn test_event_replay_causing_monitor_replay() { let payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 1_000_000).0; - do_claim_payment_along_route(&nodes[0], &[&[&nodes[1]]], false, payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], payment_preimage) + ); // At this point the `PaymentSent` event has not been processed but the full commitment signed // dance has completed. diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 2fc21eb2385..fdc44dee7b8 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -160,7 +160,9 @@ fn mpp_retry() { let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 2_000_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], payment_preimage) + ); } #[test] @@ -351,7 +353,9 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) { nodes[3].node.timer_tick_occurred(); } - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], payment_preimage) + ); } } @@ -466,7 +470,9 @@ fn test_mpp_keysend() { let ev = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events); pass_along_path(&nodes[0], expected_route[1], recv_value, payment_hash.clone(), Some(payment_secret), ev.clone(), true, Some(payment_preimage)); - claim_payment_along_route(&nodes[0], expected_route, false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], expected_route, payment_preimage) + ); } #[test] @@ -817,7 +823,9 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None); - do_claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + ); expect_payment_sent!(nodes[0], payment_preimage, Some(new_route.paths[0].hops[0].fee_msat)); } @@ -1245,7 +1253,9 @@ fn get_ldk_payment_preimage() { let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); pass_along_path(&nodes[0], &[&nodes[1]], amt_msat, payment_hash, Some(payment_secret), events.pop().unwrap(), true, Some(payment_preimage)); - claim_payment_along_route(&nodes[0], &[&[&nodes[1]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], payment_preimage) + ); } #[test] @@ -1579,7 +1589,9 @@ fn claimed_send_payment_idempotent() { // Claim the payment backwards, but note that the PaymentSent event is still pending and has // not been seen by the user. At this point, from the user perspective nothing has changed, so // we must remain just as idempotent as we were before. - do_claim_payment_along_route(&nodes[0], &[&[&nodes[1]]], false, first_payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], first_payment_preimage) + ); for _ in 0..=IDEMPOTENCY_TIMEOUT_TICKS { nodes[0].node.timer_tick_occurred(); @@ -1980,7 +1992,9 @@ fn do_test_intercepted_payment(test: InterceptTest) { let payment_preimage = nodes[2].node.get_payment_preimage(payment_hash, payment_secret).unwrap(); expect_payment_claimable!(&nodes[2], payment_hash, payment_secret, amt_msat, Some(payment_preimage), nodes[2].node.get_our_node_id()); - do_claim_payment_along_route(&nodes[0], &vec!(&vec!(&nodes[1], &nodes[2])[..]), false, payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + ); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 2); match events[0] { @@ -2270,7 +2284,9 @@ fn do_automatic_retries(test: AutoRetry) { let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 1); pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], amt_msat, payment_hash, Some(payment_secret), msg_events.pop().unwrap(), true, None); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + ); } else if test == AutoRetry::Spontaneous { nodes[0].node.send_spontaneous_payment_with_retry(Some(payment_preimage), RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0), route_params, @@ -2287,7 +2303,9 @@ fn do_automatic_retries(test: AutoRetry) { let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 1); pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], amt_msat, payment_hash, None, msg_events.pop().unwrap(), true, Some(payment_preimage)); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + ); } else if test == AutoRetry::FailAttempts { // Ensure ChannelManager will not retry a payment if it has run out of payment attempts. nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), @@ -3714,11 +3732,17 @@ fn do_test_custom_tlvs(spontaneous: bool, even_tlvs: bool, known_tlvs: bool) { match (known_tlvs, even_tlvs) { (true, _) => { nodes[1].node.claim_funds_with_known_custom_tlvs(our_payment_preimage); - let expected_total_fee_msat = pass_claimed_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], our_payment_preimage)); + let expected_total_fee_msat = pass_claimed_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], our_payment_preimage) + .with_custom_tlvs(custom_tlvs) + ); expect_payment_sent!(&nodes[0], our_payment_preimage, Some(expected_total_fee_msat)); }, (false, false) => { - claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], our_payment_preimage) + .with_custom_tlvs(custom_tlvs) + ); }, (false, true) => { nodes[1].node.claim_funds(our_payment_preimage); @@ -3805,9 +3829,12 @@ fn test_retry_custom_tlvs() { let path = &[&nodes[1], &nodes[2]]; let args = PassAlongPathArgs::new(&nodes[0], path, 1_000_000, payment_hash, events.pop().unwrap()) .with_payment_secret(payment_secret) - .with_custom_tlvs(custom_tlvs); + .with_custom_tlvs(custom_tlvs.clone()); do_pass_along_path(args); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[2]]], payment_preimage) + .with_custom_tlvs(custom_tlvs) + ); } #[test] @@ -3938,8 +3965,10 @@ fn do_test_custom_tlvs_consistency(first_tlvs: Vec<(u64, Vec)>, second_tlvs: _ => panic!("Unexpected event"), } - do_claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], - false, our_payment_preimage); + do_claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], our_payment_preimage) + .with_custom_tlvs(expected_tlvs) + ); expect_payment_sent(&nodes[0], our_payment_preimage, Some(Some(2000)), true, true); } else { // Expect fail back @@ -4102,7 +4131,9 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) { } else { expect_pending_htlcs_forwardable!(nodes[3]); expect_payment_claimable!(nodes[3], payment_hash, payment_secret, amt_msat); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage); + claim_payment_along_route( + ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], payment_preimage) + ); } }