@@ -16,7 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
16
16
use crate :: blinded_path:: { BlindedHop , BlindedPath } ;
17
17
use crate :: ln:: PaymentHash ;
18
18
use crate :: ln:: channelmanager:: { ChannelDetails , PaymentId } ;
19
- use crate :: ln:: features:: { ChannelFeatures , InvoiceFeatures , NodeFeatures } ;
19
+ use crate :: ln:: features:: { Bolt12InvoiceFeatures , ChannelFeatures , InvoiceFeatures , NodeFeatures } ;
20
20
use crate :: ln:: msgs:: { DecodeError , ErrorAction , LightningError , MAX_VALUE_MSAT } ;
21
21
use crate :: offers:: invoice:: BlindedPayInfo ;
22
22
use crate :: routing:: gossip:: { DirectedChannelInfo , EffectiveCapacity , ReadOnlyNetworkGraph , NetworkGraph , NodeId , RoutingFees } ;
@@ -536,7 +536,7 @@ impl Writeable for PaymentParameters {
536
536
let mut blinded_hints = & vec ! [ ] ;
537
537
match & self . payee {
538
538
Payee :: Clear { route_hints, .. } => clear_hints = route_hints,
539
- Payee :: Blinded ( hints ) => blinded_hints = hints ,
539
+ Payee :: Blinded { route_hints , .. } => blinded_hints = route_hints ,
540
540
}
541
541
write_tlv_fields ! ( writer, {
542
542
( 0 , self . payee. node_id( ) , option) ,
@@ -549,6 +549,7 @@ impl Writeable for PaymentParameters {
549
549
( 7 , self . previously_failed_channels, vec_type) ,
550
550
( 8 , * blinded_hints, optional_vec) ,
551
551
( 9 , self . payee. final_cltv_expiry_delta( ) , option) ,
552
+ ( 10 , self . payee. bolt12_features( ) , option) ,
552
553
} ) ;
553
554
Ok ( ( ) )
554
555
}
@@ -567,12 +568,13 @@ impl ReadableArgs<u32> for PaymentParameters {
567
568
( 7 , previously_failed_channels, vec_type) ,
568
569
( 8 , blinded_route_hints, optional_vec) ,
569
570
( 9 , final_cltv_expiry_delta, ( default_value, default_final_cltv_expiry_delta) ) ,
571
+ ( 10 , bolt12_features, option) ,
570
572
} ) ;
571
573
let clear_route_hints = route_hints. unwrap_or ( vec ! [ ] ) ;
572
574
let blinded_route_hints = blinded_route_hints. unwrap_or ( vec ! [ ] ) ;
573
575
let payee = if blinded_route_hints. len ( ) != 0 {
574
576
if clear_route_hints. len ( ) != 0 || payee_pubkey. is_some ( ) { return Err ( DecodeError :: InvalidValue ) }
575
- Payee :: Blinded ( blinded_route_hints)
577
+ Payee :: Blinded { route_hints : blinded_route_hints, features : bolt12_features }
576
578
} else {
577
579
Payee :: Clear {
578
580
route_hints : clear_route_hints,
@@ -620,7 +622,7 @@ impl PaymentParameters {
620
622
/// Creates parameters for paying to a blinded payee.
621
623
pub fn blinded ( blinded_route_hints : Vec < ( BlindedPayInfo , BlindedPath ) > ) -> Self {
622
624
Self {
623
- payee : Payee :: Blinded ( blinded_route_hints) ,
625
+ payee : Payee :: Blinded { route_hints : blinded_route_hints, features : None } ,
624
626
expiry_time : None ,
625
627
max_total_cltv_expiry_delta : DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA ,
626
628
max_path_count : DEFAULT_MAX_PATH_COUNT ,
@@ -629,13 +631,25 @@ impl PaymentParameters {
629
631
}
630
632
}
631
633
634
+ /// Includes the payee's features. Errors if the parameters were not initialized with
635
+ /// [`PaymentParameters::blinded`].
636
+ ///
637
+ /// This is not exported to bindings users since bindings don't support move semantics
638
+ pub fn with_bolt12_features ( self , features : Bolt12InvoiceFeatures ) -> Result < Self , ( ) > {
639
+ match self . payee {
640
+ Payee :: Clear { .. } => Err ( ( ) ) ,
641
+ Payee :: Blinded { route_hints, .. } =>
642
+ Ok ( Self { payee : Payee :: Blinded { route_hints, features : Some ( features) } , ..self } )
643
+ }
644
+ }
645
+
632
646
/// Includes the payee's features. Errors if the parameters were initialized with blinded payment
633
647
/// paths.
634
648
///
635
649
/// This is not exported to bindings users since bindings don't support move semantics
636
650
pub fn with_bolt11_features ( self , features : InvoiceFeatures ) -> Result < Self , ( ) > {
637
651
match self . payee {
638
- Payee :: Blinded ( _ ) => Err ( ( ) ) ,
652
+ Payee :: Blinded { .. } => Err ( ( ) ) ,
639
653
Payee :: Clear { route_hints, node_id, final_cltv_expiry_delta, .. } =>
640
654
Ok ( Self {
641
655
payee : Payee :: Clear {
@@ -651,7 +665,7 @@ impl PaymentParameters {
651
665
/// This is not exported to bindings users since bindings don't support move semantics
652
666
pub fn with_route_hints ( self , route_hints : Vec < RouteHint > ) -> Result < Self , ( ) > {
653
667
match self . payee {
654
- Payee :: Blinded ( _ ) => Err ( ( ) ) ,
668
+ Payee :: Blinded { .. } => Err ( ( ) ) ,
655
669
Payee :: Clear { node_id, features, final_cltv_expiry_delta, .. } =>
656
670
Ok ( Self {
657
671
payee : Payee :: Clear {
@@ -696,7 +710,16 @@ impl PaymentParameters {
696
710
pub enum Payee {
697
711
/// The recipient provided blinded paths and payinfo to reach them. The blinded paths themselves
698
712
/// will be included in the final [`Route`].
699
- Blinded ( Vec < ( BlindedPayInfo , BlindedPath ) > ) ,
713
+ Blinded {
714
+ /// Aggregated routing info and blinded paths, for routing to the payee without knowing their
715
+ /// node id.
716
+ route_hints : Vec < ( BlindedPayInfo , BlindedPath ) > ,
717
+ /// Features supported by the payee.
718
+ ///
719
+ /// May be set from the payee's invoice. May be `None` if the invoice does not contain any
720
+ /// features.
721
+ features : Option < Bolt12InvoiceFeatures > ,
722
+ } ,
700
723
/// The recipient included these route hints in their BOLT11 invoice.
701
724
Clear {
702
725
/// The node id of the payee.
@@ -722,6 +745,12 @@ impl Payee {
722
745
_ => None ,
723
746
}
724
747
}
748
+ fn bolt12_features ( & self ) -> & Option < Bolt12InvoiceFeatures > {
749
+ match self {
750
+ Self :: Blinded { features, .. } => features,
751
+ _ => & None ,
752
+ }
753
+ }
725
754
fn bolt11_features ( & self ) -> & Option < InvoiceFeatures > {
726
755
match self {
727
756
Self :: Clear { features, .. } => features,
@@ -736,14 +765,14 @@ impl Payee {
736
765
}
737
766
fn blinded_route_hints ( & self ) -> & [ ( BlindedPayInfo , BlindedPath ) ] {
738
767
match self {
739
- Self :: Blinded ( hints ) => & hints [ ..] ,
768
+ Self :: Blinded { route_hints , .. } => & route_hints [ ..] ,
740
769
Self :: Clear { .. } => & [ ]
741
770
}
742
771
}
743
772
744
773
fn clear_route_hints ( & self ) -> & [ RouteHint ] {
745
774
match self {
746
- Self :: Blinded ( _ ) => & [ ] ,
775
+ Self :: Blinded { .. } => & [ ] ,
747
776
Self :: Clear { route_hints, .. } => & route_hints[ ..]
748
777
}
749
778
}
@@ -1210,8 +1239,8 @@ where L::Target: Logger {
1210
1239
}
1211
1240
}
1212
1241
} ,
1213
- Payee :: Blinded ( hints ) => {
1214
- for ( _, blinded_path) in hints . iter ( ) {
1242
+ Payee :: Blinded { route_hints , .. } => {
1243
+ for ( _, blinded_path) in route_hints . iter ( ) {
1215
1244
if blinded_path. blinded_hops . len ( ) == 0 {
1216
1245
return Err ( LightningError { err : "0-hop blinded path provided" . to_owned ( ) , action : ErrorAction :: IgnoreError } ) ;
1217
1246
} else if & blinded_path. introduction_node_id == our_node_pubkey {
@@ -1302,6 +1331,8 @@ where L::Target: Logger {
1302
1331
false
1303
1332
} else if let Some ( features) = payment_params. payee . bolt11_features ( ) {
1304
1333
features. supports_basic_mpp ( )
1334
+ } else if let Some ( features) = payment_params. payee . bolt12_features ( ) {
1335
+ features. supports_basic_mpp ( )
1305
1336
} else if let Some ( payee) = payee_node_id {
1306
1337
network_nodes. get ( & payee) . map_or ( false , |node| node. announcement_info . as_ref ( ) . map_or ( false ,
1307
1338
|info| info. features . supports_basic_mpp ( ) ) )
0 commit comments