@@ -942,9 +942,15 @@ enum CandidateRouteHop<'a> {
942
942
info : DirectedChannelInfo < ' a > ,
943
943
short_channel_id : u64 ,
944
944
} ,
945
- /// A hop to the payee found in the payment invoice, though not necessarily a direct channel.
945
+ /// A hop to the payee found in the BOLT 11 payment invoice, though not necessarily a direct
946
+ /// channel.
946
947
PrivateHop {
947
948
hint : & ' a RouteHintHop ,
949
+ } ,
950
+ /// The payee's identity is concealed behind blinded paths provided in a BOLT 12 invoice.
951
+ Blinded {
952
+ hint : & ' a ( BlindedPayInfo , BlindedPath ) ,
953
+ hint_idx : usize ,
948
954
}
949
955
}
950
956
@@ -954,6 +960,7 @@ impl<'a> CandidateRouteHop<'a> {
954
960
CandidateRouteHop :: FirstHop { details } => Some ( details. get_outbound_payment_scid ( ) . unwrap ( ) ) ,
955
961
CandidateRouteHop :: PublicHop { short_channel_id, .. } => Some ( * short_channel_id) ,
956
962
CandidateRouteHop :: PrivateHop { hint } => Some ( hint. short_channel_id ) ,
963
+ CandidateRouteHop :: Blinded { .. } => None ,
957
964
}
958
965
}
959
966
@@ -963,6 +970,7 @@ impl<'a> CandidateRouteHop<'a> {
963
970
CandidateRouteHop :: FirstHop { details } => details. counterparty . features . to_context ( ) ,
964
971
CandidateRouteHop :: PublicHop { info, .. } => info. channel ( ) . features . clone ( ) ,
965
972
CandidateRouteHop :: PrivateHop { .. } => ChannelFeatures :: empty ( ) ,
973
+ CandidateRouteHop :: Blinded { .. } => ChannelFeatures :: empty ( ) ,
966
974
}
967
975
}
968
976
@@ -971,6 +979,8 @@ impl<'a> CandidateRouteHop<'a> {
971
979
CandidateRouteHop :: FirstHop { .. } => 0 ,
972
980
CandidateRouteHop :: PublicHop { info, .. } => info. direction ( ) . cltv_expiry_delta as u32 ,
973
981
CandidateRouteHop :: PrivateHop { hint } => hint. cltv_expiry_delta as u32 ,
982
+ CandidateRouteHop :: Blinded { hint, .. } =>
983
+ if hint. 1 . blinded_hops . len ( ) == 1 { 0 } else { hint. 0 . cltv_expiry_delta as u32 }
974
984
}
975
985
}
976
986
@@ -979,6 +989,8 @@ impl<'a> CandidateRouteHop<'a> {
979
989
CandidateRouteHop :: FirstHop { details } => details. next_outbound_htlc_minimum_msat ,
980
990
CandidateRouteHop :: PublicHop { info, .. } => info. direction ( ) . htlc_minimum_msat ,
981
991
CandidateRouteHop :: PrivateHop { hint } => hint. htlc_minimum_msat . unwrap_or ( 0 ) ,
992
+ CandidateRouteHop :: Blinded { hint, .. } =>
993
+ if hint. 1 . blinded_hops . len ( ) == 1 { 0 } else { hint. 0 . htlc_minimum_msat }
982
994
}
983
995
}
984
996
@@ -989,6 +1001,16 @@ impl<'a> CandidateRouteHop<'a> {
989
1001
} ,
990
1002
CandidateRouteHop :: PublicHop { info, .. } => info. direction ( ) . fees ,
991
1003
CandidateRouteHop :: PrivateHop { hint } => hint. fees ,
1004
+ CandidateRouteHop :: Blinded { hint, .. } => {
1005
+ if hint. 1 . blinded_hops . len ( ) == 1 {
1006
+ RoutingFees { base_msat : 0 , proportional_millionths : 0 }
1007
+ } else {
1008
+ RoutingFees {
1009
+ base_msat : hint. 0 . fee_base_msat ,
1010
+ proportional_millionths : hint. 0 . fee_proportional_millionths
1011
+ }
1012
+ }
1013
+ }
992
1014
}
993
1015
}
994
1016
@@ -1002,10 +1024,15 @@ impl<'a> CandidateRouteHop<'a> {
1002
1024
EffectiveCapacity :: HintMaxHTLC { amount_msat : * max } ,
1003
1025
CandidateRouteHop :: PrivateHop { hint : RouteHintHop { htlc_maximum_msat : None , .. } } =>
1004
1026
EffectiveCapacity :: Infinite ,
1027
+ CandidateRouteHop :: Blinded { hint, .. } =>
1028
+ if hint. 1 . blinded_hops . len ( ) == 1 { EffectiveCapacity :: Infinite }
1029
+ else { EffectiveCapacity :: HintMaxHTLC { amount_msat : hint. 0 . htlc_maximum_msat } }
1005
1030
}
1006
1031
}
1032
+
1007
1033
fn id ( & self , channel_direction : bool /* src_node_id < target_node_id */ ) -> CandidateHopId {
1008
1034
match self {
1035
+ CandidateRouteHop :: Blinded { hint_idx, .. } => CandidateHopId :: Blinded ( * hint_idx) ,
1009
1036
_ => CandidateHopId :: Clear ( ( self . short_channel_id ( ) . unwrap ( ) , channel_direction) ) ,
1010
1037
}
1011
1038
}
@@ -1262,6 +1289,12 @@ struct LoggedCandidateHop<'a>(&'a CandidateRouteHop<'a>);
1262
1289
impl < ' a > fmt:: Display for LoggedCandidateHop < ' a > {
1263
1290
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1264
1291
match self . 0 {
1292
+ CandidateRouteHop :: Blinded { hint, .. } => {
1293
+ "blinded route hint with introduction node id " . fmt ( f) ?;
1294
+ hint. 1 . introduction_node_id . fmt ( f) ?;
1295
+ " and blinding point " . fmt ( f) ?;
1296
+ hint. 1 . blinding_point . fmt ( f)
1297
+ } ,
1265
1298
_ => {
1266
1299
"SCID " . fmt ( f) ?;
1267
1300
self . 0 . short_channel_id ( ) . unwrap ( ) . fmt ( f)
0 commit comments