@@ -55,9 +55,7 @@ use crate::ln::channel_state::ChannelDetails;
55
55
use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
56
56
#[cfg(any(feature = "_test_utils", test))]
57
57
use crate::types::features::Bolt11InvoiceFeatures;
58
- use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, Router};
59
- #[cfg(test)]
60
- use crate::routing::router::Route;
58
+ use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, Router};
61
59
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundHTLCErr, NextPacketDetails};
62
60
use crate::ln::msgs;
63
61
use crate::ln::onion_utils;
@@ -2398,9 +2396,6 @@ where
2398
2396
fee_estimator: LowerBoundedFeeEstimator<F>,
2399
2397
chain_monitor: M,
2400
2398
tx_broadcaster: T,
2401
- #[cfg(fuzzing)]
2402
- pub router: R,
2403
- #[cfg(not(fuzzing))]
2404
2399
router: R,
2405
2400
message_router: MR,
2406
2401
@@ -4583,21 +4578,31 @@ where
4583
4578
}
4584
4579
}
4585
4580
4586
- // Deprecated send method, for testing use [`Self::send_payment`] and
4587
- // [`TestRouter::expect_find_route`] instead.
4588
- //
4589
- // [`TestRouter::expect_find_route`]: crate::util::test_utils::TestRouter::expect_find_route
4590
- #[cfg(test)]
4591
- pub(crate) fn send_payment_with_route(
4592
- &self, route: Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
4581
+ /// Sends a payment along a given route. See [`Self::send_payment`] for more info.
4582
+ ///
4583
+ /// LDK will not automatically retry this payment, though it may be manually re-sent after an
4584
+ /// [`Event::PaymentFailed`] is generated.
4585
+ pub fn send_payment_with_route(
4586
+ &self, mut route: Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
4593
4587
payment_id: PaymentId
4594
- ) -> Result<(), PaymentSendFailure > {
4588
+ ) -> Result<(), RetryableSendFailure > {
4595
4589
let best_block_height = self.best_block.read().unwrap().height;
4596
4590
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4591
+ let route_params = route.route_params.clone().unwrap_or_else(|| {
4592
+ // Create a dummy route params since they're a required parameter but unused in this case
4593
+ let (payee_node_id, cltv_delta) = route.paths.first()
4594
+ .and_then(|path| path.hops.last().map(|hop| (hop.pubkey, hop.cltv_expiry_delta as u32)))
4595
+ .unwrap_or_else(|| (PublicKey::from_slice(&[2; 32]).unwrap(), MIN_FINAL_CLTV_EXPIRY_DELTA as u32));
4596
+ let dummy_payment_params = PaymentParameters::from_node_id(payee_node_id, cltv_delta);
4597
+ RouteParameters::from_payment_params_and_value(dummy_payment_params, route.get_total_amount())
4598
+ });
4599
+ if route.route_params.is_none() { route.route_params = Some(route_params.clone()); }
4600
+ let router = FixedRouter::new(route);
4597
4601
self.pending_outbound_payments
4598
- .send_payment_with_route(&route, payment_hash, recipient_onion, payment_id,
4599
- &self.entropy_source, &self.node_signer, best_block_height,
4600
- |args| self.send_payment_along_path(args))
4602
+ .send_payment(payment_hash, recipient_onion, payment_id, Retry::Attempts(0),
4603
+ route_params, &&router, self.list_usable_channels(), || self.compute_inflight_htlcs(),
4604
+ &self.entropy_source, &self.node_signer, best_block_height, &self.logger,
4605
+ &self.pending_events, |args| self.send_payment_along_path(args))
4601
4606
}
4602
4607
4603
4608
/// Sends a payment to the route found using the provided [`RouteParameters`], retrying failed
@@ -4626,7 +4631,8 @@ where
4626
4631
/// [`ChannelManager::list_recent_payments`] for more information.
4627
4632
///
4628
4633
/// Routes are automatically found using the [`Router] provided on startup. To fix a route for a
4629
- /// particular payment, match the [`PaymentId`] passed to [`Router::find_route_with_id`].
4634
+ /// particular payment, use [`Self::send_payment_with_route`] or match the [`PaymentId`] passed to
4635
+ /// [`Router::find_route_with_id`].
4630
4636
///
4631
4637
/// [`Event::PaymentSent`]: events::Event::PaymentSent
4632
4638
/// [`Event::PaymentFailed`]: events::Event::PaymentFailed
@@ -14391,7 +14397,7 @@ mod tests {
14391
14397
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
14392
14398
use crate::ln::types::ChannelId;
14393
14399
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
14394
- use crate::ln::channelmanager::{create_recv_pending_htlc_info, HTLCForwardInfo, inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId};
14400
+ use crate::ln::channelmanager::{create_recv_pending_htlc_info, HTLCForwardInfo, inbound_payment, PaymentId, RecipientOnionFields, InterceptId};
14395
14401
use crate::ln::functional_test_utils::*;
14396
14402
use crate::ln::msgs::{self, ErrorAction};
14397
14403
use crate::ln::msgs::ChannelMessageHandler;
@@ -14822,14 +14828,17 @@ mod tests {
14822
14828
route.paths[1].hops[0].short_channel_id = chan_2_id;
14823
14829
route.paths[1].hops[1].short_channel_id = chan_4_id;
14824
14830
14825
- match nodes[0].node.send_payment_with_route(route, payment_hash,
14826
- RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0))
14827
- .unwrap_err() {
14828
- PaymentSendFailure::ParameterError(APIError::APIMisuseError { ref err }) => {
14829
- assert!(regex::Regex::new(r"Payment secret is required for multi-path payments").unwrap().is_match(err))
14830
- },
14831
- _ => panic!("unexpected error")
14831
+ nodes[0].node.send_payment_with_route(route, payment_hash,
14832
+ RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0)).unwrap();
14833
+ let events = nodes[0].node.get_and_clear_pending_events();
14834
+ assert_eq!(events.len(), 1);
14835
+ match events[0] {
14836
+ Event::PaymentFailed { reason, .. } => {
14837
+ assert_eq!(reason.unwrap(), crate::events::PaymentFailureReason::UnexpectedError);
14838
+ }
14839
+ _ => panic!()
14832
14840
}
14841
+ nodes[0].logger.assert_log_contains("lightning::ln::outbound_payment", "Payment secret is required for multi-path payments", 2);
14833
14842
assert!(nodes[0].node.list_recent_payments().is_empty());
14834
14843
}
14835
14844
0 commit comments