1010use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
1111use crate :: blinded_path:: BlindedPath ;
1212use crate :: blinded_path:: payment:: { ForwardNode , ForwardTlvs , PaymentConstraints , PaymentRelay , ReceiveTlvs } ;
13- use crate :: events:: { HTLCDestination , MessageSendEvent , MessageSendEventsProvider } ;
13+ use crate :: events:: { Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider , PaymentFailureReason } ;
1414use crate :: ln:: PaymentSecret ;
1515use crate :: ln:: channelmanager;
1616use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields } ;
@@ -21,15 +21,16 @@ use crate::ln::msgs::ChannelMessageHandler;
2121use crate :: ln:: onion_utils;
2222use crate :: ln:: onion_utils:: INVALID_ONION_BLINDING ;
2323use crate :: ln:: outbound_payment:: Retry ;
24+ use crate :: offers:: invoice:: BlindedPayInfo ;
2425use crate :: prelude:: * ;
2526use crate :: routing:: router:: { Payee , PaymentParameters , RouteParameters } ;
2627use crate :: util:: config:: UserConfig ;
2728use crate :: util:: test_utils;
2829
29- pub fn get_blinded_route_parameters (
30- amt_msat : u64 , payment_secret : PaymentSecret , node_ids : Vec < PublicKey > ,
30+ fn blinded_payment_path (
31+ payment_secret : PaymentSecret , node_ids : Vec < PublicKey > ,
3132 channel_upds : & [ & msgs:: UnsignedChannelUpdate ] , keys_manager : & test_utils:: TestKeysInterface
32- ) -> RouteParameters {
33+ ) -> ( BlindedPayInfo , BlindedPath ) {
3334 let mut intermediate_nodes = Vec :: new ( ) ;
3435 for ( node_id, chan_upd) in node_ids. iter ( ) . zip ( channel_upds) {
3536 intermediate_nodes. push ( ForwardNode {
@@ -58,13 +59,20 @@ pub fn get_blinded_route_parameters(
5859 } ,
5960 } ;
6061 let mut secp_ctx = Secp256k1 :: new ( ) ;
61- let blinded_path = BlindedPath :: new_for_payment (
62+ BlindedPath :: new_for_payment (
6263 & intermediate_nodes[ ..] , * node_ids. last ( ) . unwrap ( ) , payee_tlvs,
6364 channel_upds. last ( ) . unwrap ( ) . htlc_maximum_msat , keys_manager, & secp_ctx
64- ) . unwrap ( ) ;
65+ ) . unwrap ( )
66+ }
6567
68+ pub fn get_blinded_route_parameters (
69+ amt_msat : u64 , payment_secret : PaymentSecret , node_ids : Vec < PublicKey > ,
70+ channel_upds : & [ & msgs:: UnsignedChannelUpdate ] , keys_manager : & test_utils:: TestKeysInterface
71+ ) -> RouteParameters {
6672 RouteParameters :: from_payment_params_and_value (
67- PaymentParameters :: blinded ( vec ! [ blinded_path] ) , amt_msat
73+ PaymentParameters :: blinded ( vec ! [
74+ blinded_payment_path( payment_secret, node_ids, channel_upds, keys_manager)
75+ ] ) , amt_msat
6876 )
6977}
7078
@@ -725,3 +733,108 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
725733 expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false ,
726734 PaymentFailedConditions :: new ( ) . expected_htlc_error_data ( INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ) ;
727735}
736+
737+ #[ test]
738+ fn blinded_path_retries ( ) {
739+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
740+ // Make one blinded path's fees slightly higher so they are tried in a deterministic order.
741+ let mut higher_fee_chan_cfg = test_default_channel_config ( ) ;
742+ higher_fee_chan_cfg. channel_config . forwarding_fee_base_msat += 1 ;
743+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
744+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , Some ( higher_fee_chan_cfg) , None ] ) ;
745+ let mut nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
746+
747+ // Create this network topology so nodes[0] has a blinded route hint to retry over.
748+ // n1
749+ // / \
750+ // n0 n3
751+ // \ /
752+ // n2
753+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
754+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 2 , 1_000_000 , 0 ) ;
755+ let chan_1_3 = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 3 , 1_000_000 , 0 ) ;
756+ let chan_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) ;
757+
758+ let amt_msat = 5000 ;
759+ let ( _, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 3 ] , Some ( amt_msat) , None ) ;
760+ let route_params = {
761+ let pay_params = PaymentParameters :: blinded (
762+ vec ! [
763+ blinded_payment_path( payment_secret,
764+ vec![ nodes[ 1 ] . node. get_our_node_id( ) , nodes[ 3 ] . node. get_our_node_id( ) ] , & [ & chan_1_3. 0 . contents] ,
765+ & chanmon_cfgs[ 3 ] . keys_manager
766+ ) ,
767+ blinded_payment_path( payment_secret,
768+ vec![ nodes[ 2 ] . node. get_our_node_id( ) , nodes[ 3 ] . node. get_our_node_id( ) ] , & [ & chan_2_3. 0 . contents] ,
769+ & chanmon_cfgs[ 3 ] . keys_manager
770+ ) ,
771+ ]
772+ )
773+ . with_bolt12_features ( channelmanager:: provided_bolt12_invoice_features ( & UserConfig :: default ( ) ) )
774+ . unwrap ( ) ;
775+ RouteParameters :: from_payment_params_and_value ( pay_params, amt_msat)
776+ } ;
777+
778+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) , route_params. clone ( ) , Retry :: Attempts ( 2 ) ) . unwrap ( ) ;
779+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
780+ pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 3 ] ] ] , amt_msat, payment_hash, payment_secret) ;
781+
782+ macro_rules! fail_payment_back {
783+ ( $intro_node: expr) => {
784+ nodes[ 3 ] . node. fail_htlc_backwards( & payment_hash) ;
785+ expect_pending_htlcs_forwardable_conditions(
786+ nodes[ 3 ] . node. get_and_clear_pending_events( ) , & [ HTLCDestination :: FailedPayment { payment_hash } ]
787+ ) ;
788+ nodes[ 3 ] . node. process_pending_htlc_forwards( ) ;
789+ check_added_monitors!( nodes[ 3 ] , 1 ) ;
790+
791+ let updates = get_htlc_update_msgs!( nodes[ 3 ] , $intro_node. node. get_our_node_id( ) ) ;
792+ assert_eq!( updates. update_fail_malformed_htlcs. len( ) , 1 ) ;
793+ let update_malformed = & updates. update_fail_malformed_htlcs[ 0 ] ;
794+ assert_eq!( update_malformed. sha256_of_onion, [ 0 ; 32 ] ) ;
795+ assert_eq!( update_malformed. failure_code, INVALID_ONION_BLINDING ) ;
796+ $intro_node. node. handle_update_fail_malformed_htlc( & nodes[ 3 ] . node. get_our_node_id( ) , update_malformed) ;
797+ do_commitment_signed_dance( & $intro_node, & nodes[ 3 ] , & updates. commitment_signed, true , false ) ;
798+
799+ let updates = get_htlc_update_msgs!( $intro_node, nodes[ 0 ] . node. get_our_node_id( ) ) ;
800+ assert_eq!( updates. update_fail_htlcs. len( ) , 1 ) ;
801+ nodes[ 0 ] . node. handle_update_fail_htlc( & $intro_node. node. get_our_node_id( ) , & updates. update_fail_htlcs[ 0 ] ) ;
802+ do_commitment_signed_dance( & nodes[ 0 ] , & $intro_node, & updates. commitment_signed, false , false ) ;
803+
804+ let mut events = nodes[ 0 ] . node. get_and_clear_pending_events( ) ;
805+ assert_eq!( events. len( ) , 2 ) ;
806+ match events[ 0 ] {
807+ Event :: PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently, .. } => {
808+ assert_eq!( payment_hash, ev_payment_hash) ;
809+ assert_eq!( payment_failed_permanently, false ) ;
810+ } ,
811+ _ => panic!( "Unexpected event" ) ,
812+ }
813+ match events[ 1 ] {
814+ Event :: PendingHTLCsForwardable { .. } => { } ,
815+ _ => panic!( "Unexpected event" ) ,
816+ }
817+ nodes[ 0 ] . node. process_pending_htlc_forwards( ) ;
818+ }
819+ }
820+
821+ fail_payment_back ! ( nodes[ 1 ] ) ;
822+
823+ // Pass the retry along.
824+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
825+ let mut msg_events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
826+ assert_eq ! ( msg_events. len( ) , 1 ) ;
827+ pass_along_path ( & nodes[ 0 ] , & [ & nodes[ 2 ] , & nodes[ 3 ] ] , amt_msat, payment_hash, Some ( payment_secret) , msg_events. pop ( ) . unwrap ( ) , true , None ) ;
828+
829+ fail_payment_back ! ( nodes[ 2 ] ) ;
830+ let evs = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
831+ assert_eq ! ( evs. len( ) , 1 ) ;
832+ match evs[ 0 ] {
833+ Event :: PaymentFailed { payment_hash : ev_payment_hash, reason, .. } => {
834+ assert_eq ! ( ev_payment_hash, payment_hash) ;
835+ // We have 1 retry attempt remaining, but we're out of blinded paths to try.
836+ assert_eq ! ( reason, Some ( PaymentFailureReason :: RouteNotFound ) ) ;
837+ } ,
838+ _ => panic ! ( )
839+ }
840+ }
0 commit comments