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