@@ -48,6 +48,7 @@ pub(crate) enum PendingOutboundPayment {
48
48
session_privs : HashSet < [ u8 ; 32 ] > ,
49
49
payment_hash : PaymentHash ,
50
50
payment_secret : Option < PaymentSecret > ,
51
+ keysend_preimage : Option < PaymentPreimage > ,
51
52
pending_amt_msat : u64 ,
52
53
/// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
53
54
pending_fee_msat : Option < u64 > ,
@@ -415,7 +416,7 @@ impl OutboundPayments {
415
416
F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
416
417
u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError > ,
417
418
{
418
- self . pay_internal ( payment_id, Some ( ( payment_hash, payment_secret, retry_strategy) ) ,
419
+ self . pay_internal ( payment_id, Some ( ( payment_hash, payment_secret, None , retry_strategy) ) ,
419
420
route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer,
420
421
best_block_height, logger, & send_payment_along_path)
421
422
. map_err ( |e| { self . remove_outbound_if_all_failed ( payment_id, & e) ; e } )
@@ -432,13 +433,37 @@ impl OutboundPayments {
432
433
F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
433
434
u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError >
434
435
{
435
- let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, route, None , None , entropy_source, best_block_height) ?;
436
+ let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, None , route, None , None , entropy_source, best_block_height) ?;
436
437
self . pay_route_internal ( route, payment_hash, payment_secret, None , payment_id, None ,
437
438
onion_session_privs, node_signer, best_block_height, & send_payment_along_path)
438
439
. map_err ( |e| { self . remove_outbound_if_all_failed ( payment_id, & e) ; e } )
439
440
}
440
441
441
- pub ( super ) fn send_spontaneous_payment < ES : Deref , NS : Deref , F > (
442
+ pub ( super ) fn send_spontaneous_payment < R : Deref , ES : Deref , NS : Deref , F , L : Deref > (
443
+ & self , payment_preimage : Option < PaymentPreimage > , payment_id : PaymentId ,
444
+ retry_strategy : Retry , route_params : RouteParameters , router : & R ,
445
+ first_hops : Vec < ChannelDetails > , inflight_htlcs : InFlightHtlcs , entropy_source : & ES ,
446
+ node_signer : & NS , best_block_height : u32 , logger : & L , send_payment_along_path : F
447
+ ) -> Result < PaymentHash , PaymentSendFailure >
448
+ where
449
+ R :: Target : Router ,
450
+ ES :: Target : EntropySource ,
451
+ NS :: Target : NodeSigner ,
452
+ L :: Target : Logger ,
453
+ F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
454
+ u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError > ,
455
+ {
456
+ let preimage = payment_preimage
457
+ . unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
458
+ let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . into_inner ( ) ) ;
459
+ self . pay_internal ( payment_id, Some ( ( payment_hash, & None , Some ( preimage) , retry_strategy) ) ,
460
+ route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer,
461
+ best_block_height, logger, & send_payment_along_path)
462
+ . map ( |( ) | payment_hash)
463
+ . map_err ( |e| { self . remove_outbound_if_all_failed ( payment_id, & e) ; e } )
464
+ }
465
+
466
+ pub ( super ) fn send_spontaneous_payment_with_route < ES : Deref , NS : Deref , F > (
442
467
& self , route : & Route , payment_preimage : Option < PaymentPreimage > , payment_id : PaymentId ,
443
468
entropy_source : & ES , node_signer : & NS , best_block_height : u32 , send_payment_along_path : F
444
469
) -> Result < PaymentHash , PaymentSendFailure >
@@ -448,12 +473,10 @@ impl OutboundPayments {
448
473
F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
449
474
u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError >
450
475
{
451
- let preimage = match payment_preimage {
452
- Some ( p) => p,
453
- None => PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ,
454
- } ;
476
+ let preimage = payment_preimage
477
+ . unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
455
478
let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . into_inner ( ) ) ;
456
- let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, & route, None , None , entropy_source, best_block_height) ?;
479
+ let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, Some ( preimage ) , & route, None , None , entropy_source, best_block_height) ?;
457
480
458
481
match self . pay_route_internal ( route, payment_hash, & None , Some ( preimage) , payment_id, None , onion_session_privs, node_signer, best_block_height, & send_payment_along_path) {
459
482
Ok ( ( ) ) => Ok ( payment_hash) ,
@@ -511,7 +534,7 @@ impl OutboundPayments {
511
534
512
535
fn pay_internal < R : Deref , NS : Deref , ES : Deref , F , L : Deref > (
513
536
& self , payment_id : PaymentId ,
514
- initial_send_info : Option < ( PaymentHash , & Option < PaymentSecret > , Retry ) > ,
537
+ initial_send_info : Option < ( PaymentHash , & Option < PaymentSecret > , Option < PaymentPreimage > , Retry ) > ,
515
538
route_params : RouteParameters , router : & R , first_hops : Vec < ChannelDetails > ,
516
539
inflight_htlcs : InFlightHtlcs , entropy_source : & ES , node_signer : & NS , best_block_height : u32 ,
517
540
logger : & L , send_payment_along_path : & F ,
@@ -539,8 +562,8 @@ impl OutboundPayments {
539
562
err : format ! ( "Failed to find a route for payment {}: {:?}" , log_bytes!( payment_id. 0 ) , e) , // TODO: add APIError::RouteNotFound
540
563
} ) ) ?;
541
564
542
- let res = if let Some ( ( payment_hash, payment_secret, retry_strategy) ) = initial_send_info {
543
- let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, & route, Some ( retry_strategy) , Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height) ?;
565
+ let res = if let Some ( ( payment_hash, payment_secret, keysend_preimage , retry_strategy) ) = initial_send_info {
566
+ let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, keysend_preimage , & route, Some ( retry_strategy) , Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height) ?;
544
567
self . pay_route_internal ( & route, payment_hash, payment_secret, None , payment_id, None , onion_session_privs, node_signer, best_block_height, send_payment_along_path)
545
568
} else {
546
569
self . retry_payment_with_route ( & route, payment_id, entropy_source, node_signer, best_block_height, send_payment_along_path)
@@ -596,21 +619,21 @@ impl OutboundPayments {
596
619
onion_session_privs. push ( entropy_source. get_secure_random_bytes ( ) ) ;
597
620
}
598
621
599
- let ( total_msat, payment_hash, payment_secret) = {
622
+ let ( total_msat, payment_hash, payment_secret, keysend_preimage ) = {
600
623
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
601
624
match outbounds. get_mut ( & payment_id) {
602
625
Some ( payment) => {
603
626
let res = match payment {
604
627
PendingOutboundPayment :: Retryable {
605
- total_msat, payment_hash, payment_secret, pending_amt_msat, ..
628
+ total_msat, payment_hash, keysend_preimage , payment_secret, pending_amt_msat, ..
606
629
} => {
607
630
let retry_amt_msat: u64 = route. paths . iter ( ) . map ( |path| path. last ( ) . unwrap ( ) . fee_msat ) . sum ( ) ;
608
631
if retry_amt_msat + * pending_amt_msat > * total_msat * ( 100 + RETRY_OVERFLOW_PERCENTAGE ) / 100 {
609
632
return Err ( PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError {
610
633
err : format ! ( "retry_amt_msat of {} will put pending_amt_msat (currently: {}) more than 10% over total_payment_amt_msat of {}" , retry_amt_msat, pending_amt_msat, total_msat) . to_string ( )
611
634
} ) )
612
635
}
613
- ( * total_msat, * payment_hash, * payment_secret)
636
+ ( * total_msat, * payment_hash, * payment_secret, * keysend_preimage )
614
637
} ,
615
638
PendingOutboundPayment :: Legacy { .. } => {
616
639
return Err ( PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError {
@@ -645,7 +668,7 @@ impl OutboundPayments {
645
668
} ) ) ,
646
669
}
647
670
} ;
648
- self . pay_route_internal ( route, payment_hash, & payment_secret, None , payment_id, Some ( total_msat) , onion_session_privs, node_signer, best_block_height, & send_payment_along_path)
671
+ self . pay_route_internal ( route, payment_hash, & payment_secret, keysend_preimage , payment_id, Some ( total_msat) , onion_session_privs, node_signer, best_block_height, & send_payment_along_path)
649
672
}
650
673
651
674
pub ( super ) fn send_probe < ES : Deref , NS : Deref , F > (
@@ -669,7 +692,7 @@ impl OutboundPayments {
669
692
}
670
693
671
694
let route = Route { paths : vec ! [ hops] , payment_params : None } ;
672
- let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, & route, None , None , entropy_source, best_block_height) ?;
695
+ let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, None , & route, None , None , entropy_source, best_block_height) ?;
673
696
674
697
match self . pay_route_internal ( & route, payment_hash, & None , None , payment_id, None , onion_session_privs, node_signer, best_block_height, & send_payment_along_path) {
675
698
Ok ( ( ) ) => Ok ( ( payment_hash, payment_id) ) ,
@@ -685,13 +708,13 @@ impl OutboundPayments {
685
708
& self , payment_hash : PaymentHash , payment_secret : Option < PaymentSecret > , payment_id : PaymentId ,
686
709
route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
687
710
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
688
- self . add_new_pending_payment ( payment_hash, payment_secret, payment_id, route, retry_strategy, None , entropy_source, best_block_height)
711
+ self . add_new_pending_payment ( payment_hash, payment_secret, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height)
689
712
}
690
713
691
714
pub ( super ) fn add_new_pending_payment < ES : Deref > (
692
715
& self , payment_hash : PaymentHash , payment_secret : Option < PaymentSecret > , payment_id : PaymentId ,
693
- route : & Route , retry_strategy : Option < Retry > , payment_params : Option < PaymentParameters > ,
694
- entropy_source : & ES , best_block_height : u32
716
+ keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
717
+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
695
718
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
696
719
let mut onion_session_privs = Vec :: with_capacity ( route. paths . len ( ) ) ;
697
720
for _ in 0 ..route. paths . len ( ) {
@@ -711,6 +734,7 @@ impl OutboundPayments {
711
734
pending_fee_msat : Some ( 0 ) ,
712
735
payment_hash,
713
736
payment_secret,
737
+ keysend_preimage,
714
738
starting_block_height : best_block_height,
715
739
total_msat : route. get_total_amount ( ) ,
716
740
} ) ;
@@ -1153,6 +1177,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1153
1177
( 2 , payment_hash, required) ,
1154
1178
( 3 , payment_params, option) ,
1155
1179
( 4 , payment_secret, option) ,
1180
+ ( 5 , keysend_preimage, option) ,
1156
1181
( 6 , total_msat, required) ,
1157
1182
( 8 , pending_amt_msat, required) ,
1158
1183
( 10 , starting_block_height, required) ,
@@ -1247,9 +1272,9 @@ mod tests {
1247
1272
Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } ) ) ;
1248
1273
1249
1274
let err = if on_retry {
1250
- outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , None , PaymentId ( [ 0 ; 32 ] ) ,
1251
- & Route { paths : vec ! [ ] , payment_params : None } , Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params . payment_params . clone ( ) ) ,
1252
- & & keys_manager, 0 ) . unwrap ( ) ;
1275
+ outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , None , PaymentId ( [ 0 ; 32 ] ) , None ,
1276
+ & Route { paths : vec ! [ ] , payment_params : None } , Some ( Retry :: Attempts ( 1 ) ) ,
1277
+ Some ( route_params . payment_params . clone ( ) ) , & & keys_manager, 0 ) . unwrap ( ) ;
1253
1278
outbound_payments. pay_internal (
1254
1279
PaymentId ( [ 0 ; 32 ] ) , None , route_params, & & router, vec ! [ ] , InFlightHtlcs :: new ( ) ,
1255
1280
& & keys_manager, & & keys_manager, 0 , & & logger, & |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
0 commit comments