@@ -510,11 +510,8 @@ pub enum Bolt12PaymentError {
510
510
UnexpectedInvoice ,
511
511
/// Payment for an invoice with the corresponding [`PaymentId`] was already initiated.
512
512
DuplicateInvoice ,
513
- /// The [`BlindedPath`]s provided are too large and caused us to exceed the maximum onion hop data
514
- /// size of 1300 bytes.
515
- ///
516
- /// [`BlindedPath`]: crate::blinded_path::BlindedPath
517
- OnionPacketSizeExceeded ,
513
+ /// The invoice was valid for the corresponding [`PaymentId`], but sending the payment failed.
514
+ SendingFailed ( RetryableSendFailure ) ,
518
515
}
519
516
520
517
/// Indicates that we failed to send a payment probe. Further errors may be surfaced later via
@@ -803,20 +800,24 @@ impl OutboundPayments {
803
800
{
804
801
let payment_hash = invoice. payment_hash ( ) ;
805
802
let max_total_routing_fee_msat;
803
+ let retry_strategy;
806
804
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
807
805
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
808
- PendingOutboundPayment :: AwaitingInvoice { retry_strategy, max_total_routing_fee_msat : max_total_fee, .. } => {
806
+ PendingOutboundPayment :: AwaitingInvoice {
807
+ retry_strategy : retry, max_total_routing_fee_msat : max_total_fee, ..
808
+ } => {
809
+ retry_strategy = Some ( * retry) ;
809
810
max_total_routing_fee_msat = * max_total_fee;
810
811
* entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
811
812
payment_hash,
812
- retry_strategy : * retry_strategy ,
813
+ retry_strategy : * retry ,
813
814
max_total_routing_fee_msat,
814
815
} ;
815
816
} ,
816
817
_ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
817
818
} ,
818
819
hash_map:: Entry :: Vacant ( _) => return Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
819
- } ;
820
+ }
820
821
821
822
let mut payment_params = PaymentParameters :: from_bolt12_invoice ( & invoice) ;
822
823
@@ -842,25 +843,64 @@ impl OutboundPayments {
842
843
let mut route_params = RouteParameters :: from_payment_params_and_value (
843
844
payment_params, amount_msat
844
845
) ;
845
- onion_utils:: set_max_path_length (
846
- & mut route_params, & RecipientOnionFields :: spontaneous_empty ( ) , None , best_block_height
847
- )
848
- . map_err ( |( ) | {
849
- log_error ! ( logger, "Can't construct an onion packet without exceeding 1300-byte onion \
850
- hop_data length for payment with id {} and hash {}", payment_id, payment_hash) ;
851
- Bolt12PaymentError :: OnionPacketSizeExceeded
852
- } ) ?;
853
846
854
847
if let Some ( max_fee_msat) = max_total_routing_fee_msat {
855
848
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
856
849
}
857
850
858
- self . find_route_and_send_payment (
859
- payment_hash, payment_id, route_params, router, first_hops, & inflight_htlcs,
860
- entropy_source, node_signer, best_block_height, logger, pending_events,
861
- & send_payment_along_path
851
+ let recipient_onion = RecipientOnionFields {
852
+ payment_secret : None ,
853
+ payment_metadata : None ,
854
+ custom_tlvs : vec ! [ ] ,
855
+ } ;
856
+ let route = match self . find_initial_route (
857
+ payment_id, payment_hash, & recipient_onion, None , & mut route_params, router,
858
+ & first_hops, & inflight_htlcs, node_signer, best_block_height, logger,
859
+ ) {
860
+ Ok ( route) => route,
861
+ Err ( e) => {
862
+ let reason = match e {
863
+ RetryableSendFailure :: PaymentExpired => PaymentFailureReason :: PaymentExpired ,
864
+ RetryableSendFailure :: RouteNotFound => PaymentFailureReason :: RouteNotFound ,
865
+ RetryableSendFailure :: DuplicatePayment => PaymentFailureReason :: UnexpectedError ,
866
+ RetryableSendFailure :: OnionPacketSizeExceeded => PaymentFailureReason :: UnexpectedError ,
867
+ } ;
868
+ self . abandon_payment ( payment_id, reason, pending_events) ;
869
+ return Err ( Bolt12PaymentError :: SendingFailed ( e) ) ;
870
+ } ,
871
+ } ;
872
+
873
+ let payment_params = Some ( route_params. payment_params . clone ( ) ) ;
874
+ let ( retryable_payment, onion_session_privs) = self . create_pending_payment (
875
+ payment_hash, recipient_onion. clone ( ) , None , & route,
876
+ retry_strategy, payment_params, entropy_source, best_block_height
862
877
) ;
878
+ match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
879
+ hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
880
+ PendingOutboundPayment :: InvoiceReceived { .. } => {
881
+ * entry. into_mut ( ) = retryable_payment;
882
+ } ,
883
+ _ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
884
+ } ,
885
+ hash_map:: Entry :: Vacant ( _) => return Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
886
+ }
863
887
888
+ let result = self . pay_route_internal (
889
+ & route, payment_hash, & recipient_onion, None , payment_id,
890
+ Some ( route_params. final_value_msat ) , onion_session_privs, node_signer,
891
+ best_block_height, & send_payment_along_path
892
+ ) ;
893
+ log_info ! (
894
+ logger, "Sending payment with id {} and hash {} returned {:?}" , payment_id,
895
+ payment_hash, result
896
+ ) ;
897
+ if let Err ( e) = result {
898
+ self . handle_pay_route_err (
899
+ e, payment_id, payment_hash, route, route_params, router, first_hops,
900
+ & inflight_htlcs, entropy_source, node_signer, best_block_height, logger,
901
+ pending_events, & send_payment_along_path
902
+ ) ;
903
+ }
864
904
Ok ( ( ) )
865
905
}
866
906
@@ -928,25 +968,17 @@ impl OutboundPayments {
928
968
!pmt. is_awaiting_invoice ( ) )
929
969
}
930
970
931
- /// Errors immediately on [`RetryableSendFailure`] error conditions. Otherwise, further errors may
932
- /// be surfaced asynchronously via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`].
933
- ///
934
- /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
935
- /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
936
- fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
937
- & self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
938
- keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
939
- router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
940
- node_signer : & NS , best_block_height : u32 , logger : & L ,
941
- pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > , send_payment_along_path : SP ,
942
- ) -> Result < ( ) , RetryableSendFailure >
971
+ fn find_initial_route < R : Deref , NS : Deref , IH , L : Deref > (
972
+ & self , payment_id : PaymentId , payment_hash : PaymentHash ,
973
+ recipient_onion : & RecipientOnionFields , keysend_preimage : Option < PaymentPreimage > ,
974
+ route_params : & mut RouteParameters , router : & R , first_hops : & Vec < ChannelDetails > ,
975
+ inflight_htlcs : & IH , node_signer : & NS , best_block_height : u32 , logger : & L ,
976
+ ) -> Result < Route , RetryableSendFailure >
943
977
where
944
978
R :: Target : Router ,
945
- ES :: Target : EntropySource ,
946
979
NS :: Target : NodeSigner ,
947
980
L :: Target : Logger ,
948
981
IH : Fn ( ) -> InFlightHtlcs ,
949
- SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
950
982
{
951
983
#[ cfg( feature = "std" ) ] {
952
984
if has_expired ( & route_params) {
@@ -957,7 +989,7 @@ impl OutboundPayments {
957
989
}
958
990
959
991
onion_utils:: set_max_path_length (
960
- & mut route_params, & recipient_onion, keysend_preimage, best_block_height
992
+ route_params, recipient_onion, keysend_preimage, best_block_height
961
993
)
962
994
. map_err ( |( ) | {
963
995
log_error ! ( logger, "Can't construct an onion packet without exceeding 1300-byte onion \
@@ -966,7 +998,7 @@ impl OutboundPayments {
966
998
} ) ?;
967
999
968
1000
let mut route = router. find_route_with_id (
969
- & node_signer. get_node_id ( Recipient :: Node ) . unwrap ( ) , & route_params,
1001
+ & node_signer. get_node_id ( Recipient :: Node ) . unwrap ( ) , route_params,
970
1002
Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs ( ) ,
971
1003
payment_hash, payment_id,
972
1004
) . map_err ( |_| {
@@ -975,12 +1007,40 @@ impl OutboundPayments {
975
1007
RetryableSendFailure :: RouteNotFound
976
1008
} ) ?;
977
1009
978
- if route. route_params . as_ref ( ) != Some ( & route_params) {
1010
+ if route. route_params . as_ref ( ) != Some ( route_params) {
979
1011
debug_assert ! ( false ,
980
1012
"Routers are expected to return a Route which includes the requested RouteParameters" ) ;
981
1013
route. route_params = Some ( route_params. clone ( ) ) ;
982
1014
}
983
1015
1016
+ Ok ( route)
1017
+ }
1018
+
1019
+ /// Errors immediately on [`RetryableSendFailure`] error conditions. Otherwise, further errors may
1020
+ /// be surfaced asynchronously via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`].
1021
+ ///
1022
+ /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
1023
+ /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
1024
+ fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1025
+ & self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1026
+ keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
1027
+ router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
1028
+ node_signer : & NS , best_block_height : u32 , logger : & L ,
1029
+ pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > , send_payment_along_path : SP ,
1030
+ ) -> Result < ( ) , RetryableSendFailure >
1031
+ where
1032
+ R :: Target : Router ,
1033
+ ES :: Target : EntropySource ,
1034
+ NS :: Target : NodeSigner ,
1035
+ L :: Target : Logger ,
1036
+ IH : Fn ( ) -> InFlightHtlcs ,
1037
+ SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
1038
+ {
1039
+ let route = self . find_initial_route (
1040
+ payment_id, payment_hash, & recipient_onion, keysend_preimage, & mut route_params, router,
1041
+ & first_hops, & inflight_htlcs, node_signer, best_block_height, logger,
1042
+ ) ?;
1043
+
984
1044
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
985
1045
recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
986
1046
Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
@@ -1115,23 +1175,13 @@ impl OutboundPayments {
1115
1175
} ,
1116
1176
PendingOutboundPayment :: AwaitingInvoice { .. } => {
1117
1177
log_error ! ( logger, "Payment not yet sent" ) ;
1178
+ debug_assert ! ( false ) ;
1118
1179
return
1119
1180
} ,
1120
- PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy, .. } => {
1121
- let total_amount = route_params. final_value_msat ;
1122
- let recipient_onion = RecipientOnionFields {
1123
- payment_secret : None ,
1124
- payment_metadata : None ,
1125
- custom_tlvs : vec ! [ ] ,
1126
- } ;
1127
- let retry_strategy = Some ( * retry_strategy) ;
1128
- let payment_params = Some ( route_params. payment_params . clone ( ) ) ;
1129
- let ( retryable_payment, onion_session_privs) = self . create_pending_payment (
1130
- * payment_hash, recipient_onion. clone ( ) , None , & route,
1131
- retry_strategy, payment_params, entropy_source, best_block_height
1132
- ) ;
1133
- * payment. into_mut ( ) = retryable_payment;
1134
- ( total_amount, recipient_onion, None , onion_session_privs)
1181
+ PendingOutboundPayment :: InvoiceReceived { .. } => {
1182
+ log_error ! ( logger, "Payment already initiating" ) ;
1183
+ debug_assert ! ( false ) ;
1184
+ return
1135
1185
} ,
1136
1186
PendingOutboundPayment :: Fulfilled { .. } => {
1137
1187
log_error ! ( logger, "Payment already completed" ) ;
@@ -2273,7 +2323,7 @@ mod tests {
2273
2323
&&keys_manager, & EmptyNodeIdLookUp { } , & secp_ctx, 0 , &&logger, & pending_events,
2274
2324
|_| panic!( )
2275
2325
) ,
2276
- Ok ( ( ) ) ,
2326
+ Err ( Bolt12PaymentError :: SendingFailed ( RetryableSendFailure :: PaymentExpired ) ) ,
2277
2327
) ;
2278
2328
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2279
2329
@@ -2334,7 +2384,7 @@ mod tests {
2334
2384
&&keys_manager, & EmptyNodeIdLookUp { } , & secp_ctx, 0 , &&logger, & pending_events,
2335
2385
|_| panic!( )
2336
2386
) ,
2337
- Ok ( ( ) ) ,
2387
+ Err ( Bolt12PaymentError :: SendingFailed ( RetryableSendFailure :: RouteNotFound ) ) ,
2338
2388
) ;
2339
2389
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2340
2390
0 commit comments