@@ -14,9 +14,10 @@ use bitcoin::hashes::Hash;
14
14
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
15
15
16
16
use crate :: blinded_path:: { BlindedHop , BlindedPath } ;
17
+ use crate :: blinded_path:: payment:: { ForwardNode , ForwardTlvs , PaymentConstraints , PaymentRelay , ReceiveTlvs } ;
17
18
use crate :: ln:: PaymentHash ;
18
19
use crate :: ln:: channelmanager:: { ChannelDetails , PaymentId } ;
19
- use crate :: ln:: features:: { Bolt11InvoiceFeatures , Bolt12InvoiceFeatures , ChannelFeatures , NodeFeatures } ;
20
+ use crate :: ln:: features:: { BlindedHopFeatures , Bolt11InvoiceFeatures , Bolt12InvoiceFeatures , ChannelFeatures , NodeFeatures } ;
20
21
use crate :: ln:: msgs:: { DecodeError , ErrorAction , LightningError , MAX_VALUE_MSAT } ;
21
22
use crate :: offers:: invoice:: { BlindedPayInfo , Bolt12Invoice } ;
22
23
use crate :: onion_message:: { DefaultMessageRouter , Destination , MessageRouter , OnionMessagePath } ;
@@ -82,6 +83,57 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
82
83
& random_seed_bytes
83
84
)
84
85
}
86
+
87
+ fn create_blinded_payment_paths <
88
+ ES : EntropySource + ?Sized , T : secp256k1:: Signing + secp256k1:: Verification
89
+ > (
90
+ & self , recipient : PublicKey , first_hops : Vec < ChannelDetails > , tlvs : ReceiveTlvs ,
91
+ amount_msats : u64 , entropy_source : & ES , secp_ctx : & Secp256k1 < T >
92
+ ) -> Result < Vec < ( BlindedPayInfo , BlindedPath ) > , ( ) > {
93
+ // Limit the number of blinded paths that are computed.
94
+ const MAX_PAYMENT_PATHS : usize = 3 ;
95
+
96
+ // Ensure peers have at least three channels so that it is more difficult to infer the
97
+ // recipient's node_id.
98
+ const MIN_PEER_CHANNELS : usize = 3 ;
99
+
100
+ let network_graph = self . network_graph . deref ( ) . read_only ( ) ;
101
+ first_hops. into_iter ( )
102
+ . filter ( |details| details. is_public )
103
+ . filter ( |details| details. counterparty . features . supports_route_blinding ( ) )
104
+ . filter ( |details| amount_msats <= details. inbound_capacity_msat )
105
+ . filter ( |details| amount_msats >= details. inbound_htlc_minimum_msat . unwrap_or ( 0 ) )
106
+ . filter ( |details| amount_msats <= details. inbound_htlc_maximum_msat . unwrap_or ( 0 ) )
107
+ . filter ( |details| network_graph
108
+ . node ( & NodeId :: from_pubkey ( & details. counterparty . node_id ) )
109
+ . map ( |node_info| node_info. channels . len ( ) >= MIN_PEER_CHANNELS )
110
+ . unwrap_or ( false )
111
+ )
112
+ . map ( |details| {
113
+ let short_channel_id = details. get_inbound_payment_scid ( ) . unwrap ( ) ;
114
+ let payment_relay: PaymentRelay = details. counterparty . forwarding_info . unwrap ( ) . into ( ) ;
115
+ let payment_constraints = PaymentConstraints {
116
+ max_cltv_expiry : tlvs. payment_constraints . max_cltv_expiry
117
+ + payment_relay. cltv_expiry_delta as u32 ,
118
+ htlc_minimum_msat : details. inbound_htlc_minimum_msat . unwrap_or ( 0 ) ,
119
+ } ;
120
+ let forward_node = ForwardNode {
121
+ tlvs : ForwardTlvs {
122
+ short_channel_id,
123
+ payment_relay,
124
+ payment_constraints,
125
+ features : BlindedHopFeatures :: empty ( ) ,
126
+ } ,
127
+ node_id : details. counterparty . node_id ,
128
+ htlc_maximum_msat : details. inbound_htlc_maximum_msat . unwrap_or ( 0 ) ,
129
+ } ;
130
+ BlindedPath :: new_for_payment (
131
+ & [ forward_node] , recipient, tlvs. clone ( ) , u64:: MAX , entropy_source, secp_ctx
132
+ )
133
+ } )
134
+ . take ( MAX_PAYMENT_PATHS )
135
+ . collect ( )
136
+ }
85
137
}
86
138
87
139
impl < G : Deref < Target = NetworkGraph < L > > + Clone , L : Deref , S : Deref , SP : Sized , Sc : ScoreLookUp < ScoreParams = SP > > MessageRouter for DefaultRouter < G , L , S , SP , Sc > where
@@ -129,6 +181,16 @@ pub trait Router: MessageRouter {
129
181
) -> Result < Route , LightningError > {
130
182
self . find_route ( payer, route_params, first_hops, inflight_htlcs)
131
183
}
184
+
185
+ /// Creates [`BlindedPath`]s for payment to the `recipient` node. The channels in `first_hops`
186
+ /// are assumed to be with the `recipient`'s peers. The payment secret and any constraints are
187
+ /// given in `tlvs`.
188
+ fn create_blinded_payment_paths <
189
+ ES : EntropySource + ?Sized , T : secp256k1:: Signing + secp256k1:: Verification
190
+ > (
191
+ & self , recipient : PublicKey , first_hops : Vec < ChannelDetails > , tlvs : ReceiveTlvs ,
192
+ amount_msats : u64 , entropy_source : & ES , secp_ctx : & Secp256k1 < T >
193
+ ) -> Result < Vec < ( BlindedPayInfo , BlindedPath ) > , ( ) > ;
132
194
}
133
195
134
196
/// [`ScoreLookUp`] implementation that factors in in-flight HTLC liquidity.
0 commit comments