@@ -21,7 +21,6 @@ use crate::ln::channel_state::CounterpartyForwardingInfo;
2121use crate :: ln:: features:: BlindedHopFeatures ;
2222use crate :: ln:: msgs:: DecodeError ;
2323use crate :: ln:: onion_utils;
24- use crate :: offers:: invoice:: BlindedPayInfo ;
2524use crate :: offers:: invoice_request:: InvoiceRequestFields ;
2625use crate :: offers:: offer:: OfferId ;
2726use crate :: routing:: gossip:: { NodeId , ReadOnlyNetworkGraph } ;
@@ -34,29 +33,59 @@ use core::ops::Deref;
3433#[ allow( unused_imports) ]
3534use crate :: prelude:: * ;
3635
37- /// A blinded path to be used for sending or receiving a payment, hiding the identity of the
38- /// recipient.
39- #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
40- pub struct BlindedPaymentPath ( pub ( super ) BlindedPath ) ;
36+ /// Information needed to route a payment across a [`BlindedPaymentPath`].
37+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
38+ pub struct BlindedPayInfo {
39+ /// Base fee charged (in millisatoshi) for the entire blinded path.
40+ pub fee_base_msat : u32 ,
4141
42- impl Writeable for BlindedPaymentPath {
43- fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
44- self . 0 . write ( w)
45- }
42+ /// Liquidity fee charged (in millionths of the amount transferred) for the entire blinded path
43+ /// (i.e., 10,000 is 1%).
44+ pub fee_proportional_millionths : u32 ,
45+
46+ /// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for the entire blinded
47+ /// path.
48+ pub cltv_expiry_delta : u16 ,
49+
50+ /// The minimum HTLC value (in millisatoshi) that is acceptable to all channel peers on the
51+ /// blinded path from the introduction node to the recipient, accounting for any fees, i.e., as
52+ /// seen by the recipient.
53+ pub htlc_minimum_msat : u64 ,
54+
55+ /// The maximum HTLC value (in millisatoshi) that is acceptable to all channel peers on the
56+ /// blinded path from the introduction node to the recipient, accounting for any fees, i.e., as
57+ /// seen by the recipient.
58+ pub htlc_maximum_msat : u64 ,
59+
60+ /// Features set in `encrypted_data_tlv` for the `encrypted_recipient_data` TLV record in an
61+ /// onion payload.
62+ pub features : BlindedHopFeatures ,
4663}
4764
48- impl Readable for BlindedPaymentPath {
49- fn read < R : io:: Read > ( r : & mut R ) -> Result < Self , DecodeError > {
50- Ok ( Self ( BlindedPath :: read ( r) ?) )
51- }
65+ impl_writeable ! ( BlindedPayInfo , {
66+ fee_base_msat,
67+ fee_proportional_millionths,
68+ cltv_expiry_delta,
69+ htlc_minimum_msat,
70+ htlc_maximum_msat,
71+ features
72+ } ) ;
73+
74+ /// A blinded path to be used for sending or receiving a payment, hiding the identity of the
75+ /// recipient.
76+ #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
77+ pub struct BlindedPaymentPath {
78+ pub ( super ) inner_path : BlindedPath ,
79+ /// The [`BlindedPayInfo`] used to pay this blinded path.
80+ pub payinfo : BlindedPayInfo ,
5281}
5382
5483impl BlindedPaymentPath {
5584 /// Create a one-hop blinded path for a payment.
5685 pub fn one_hop < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
5786 payee_node_id : PublicKey , payee_tlvs : ReceiveTlvs , min_final_cltv_expiry_delta : u16 ,
5887 entropy_source : ES , secp_ctx : & Secp256k1 < T >
59- ) -> Result < ( BlindedPayInfo , Self ) , ( ) > where ES :: Target : EntropySource {
88+ ) -> Result < Self , ( ) > where ES :: Target : EntropySource {
6089 // This value is not considered in pathfinding for 1-hop blinded paths, because it's intended to
6190 // be in relation to a specific channel.
6291 let htlc_maximum_msat = u64:: max_value ( ) ;
@@ -77,7 +106,7 @@ impl BlindedPaymentPath {
77106 intermediate_nodes : & [ ForwardNode ] , payee_node_id : PublicKey , payee_tlvs : ReceiveTlvs ,
78107 htlc_maximum_msat : u64 , min_final_cltv_expiry_delta : u16 , entropy_source : ES ,
79108 secp_ctx : & Secp256k1 < T >
80- ) -> Result < ( BlindedPayInfo , Self ) , ( ) > where ES :: Target : EntropySource {
109+ ) -> Result < Self , ( ) > where ES :: Target : EntropySource {
81110 let introduction_node = IntroductionNode :: NodeId (
82111 intermediate_nodes. first ( ) . map_or ( payee_node_id, |n| n. node_id )
83112 ) ;
@@ -87,38 +116,41 @@ impl BlindedPaymentPath {
87116 let blinded_payinfo = compute_payinfo (
88117 intermediate_nodes, & payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta
89118 ) ?;
90- Ok ( ( blinded_payinfo, Self ( BlindedPath {
91- introduction_node,
92- blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
93- blinded_hops : blinded_hops (
94- secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, & blinding_secret
95- ) . map_err ( |_| ( ) ) ?,
96- } ) ) )
119+ Ok ( Self {
120+ inner_path : BlindedPath {
121+ introduction_node,
122+ blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
123+ blinded_hops : blinded_hops (
124+ secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, & blinding_secret
125+ ) . map_err ( |_| ( ) ) ?,
126+ } ,
127+ payinfo : blinded_payinfo
128+ } )
97129 }
98130
99131 /// Returns the introduction [`NodeId`] of the blinded path, if it is publicly reachable (i.e.,
100132 /// it is found in the network graph).
101133 pub fn public_introduction_node_id < ' a > (
102134 & self , network_graph : & ' a ReadOnlyNetworkGraph
103135 ) -> Option < & ' a NodeId > {
104- self . 0 . public_introduction_node_id ( network_graph)
136+ self . inner_path . public_introduction_node_id ( network_graph)
105137 }
106138
107139 /// The [`IntroductionNode`] of the blinded path.
108140 pub fn introduction_node ( & self ) -> & IntroductionNode {
109- & self . 0 . introduction_node
141+ & self . inner_path . introduction_node
110142 }
111143
112144 /// Used by the [`IntroductionNode`] to decrypt its [`encrypted_payload`] to forward the payment.
113145 ///
114146 /// [`encrypted_payload`]: BlindedHop::encrypted_payload
115147 pub fn blinding_point ( & self ) -> PublicKey {
116- self . 0 . blinding_point
148+ self . inner_path . blinding_point
117149 }
118150
119151 /// The [`BlindedHop`]s within the blinded path.
120152 pub fn blinded_hops ( & self ) -> & [ BlindedHop ] {
121- & self . 0 . blinded_hops
153+ & self . inner_path . blinded_hops
122154 }
123155
124156 /// Advance the blinded onion payment path by one hop, making the second hop into the new
@@ -133,9 +165,9 @@ impl BlindedPaymentPath {
133165 NL :: Target : NodeIdLookUp ,
134166 T : secp256k1:: Signing + secp256k1:: Verification ,
135167 {
136- let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & self . 0 . blinding_point , None ) ?;
168+ let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & self . inner_path . blinding_point , None ) ?;
137169 let rho = onion_utils:: gen_rho_from_shared_secret ( & control_tlvs_ss. secret_bytes ( ) ) ;
138- let encrypted_control_tlvs = & self . 0 . blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
170+ let encrypted_control_tlvs = & self . inner_path . blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
139171 let mut s = Cursor :: new ( encrypted_control_tlvs) ;
140172 let mut reader = FixedLengthReader :: new ( & mut s, encrypted_control_tlvs. len ( ) as u64 ) ;
141173 match ChaChaPolyReadAdapter :: read ( & mut reader, rho) {
@@ -147,31 +179,43 @@ impl BlindedPaymentPath {
147179 None => return Err ( ( ) ) ,
148180 } ;
149181 let mut new_blinding_point = onion_utils:: next_hop_pubkey (
150- secp_ctx, self . 0 . blinding_point , control_tlvs_ss. as_ref ( )
182+ secp_ctx, self . inner_path . blinding_point , control_tlvs_ss. as_ref ( )
151183 ) . map_err ( |_| ( ) ) ?;
152- mem:: swap ( & mut self . 0 . blinding_point , & mut new_blinding_point) ;
153- self . 0 . introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
154- self . 0 . blinded_hops . remove ( 0 ) ;
184+ mem:: swap ( & mut self . inner_path . blinding_point , & mut new_blinding_point) ;
185+ self . inner_path . introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
186+ self . inner_path . blinded_hops . remove ( 0 ) ;
155187 Ok ( ( ) )
156188 } ,
157189 _ => Err ( ( ) )
158190 }
159191 }
160192
193+ pub ( crate ) fn inner_blinded_path ( & self ) -> & BlindedPath {
194+ & self . inner_path
195+ }
196+
197+ pub ( crate ) fn from_parts ( inner_path : BlindedPath , payinfo : BlindedPayInfo ) -> Self {
198+ Self { inner_path, payinfo }
199+ }
200+
161201 #[ cfg( any( test, fuzzing) ) ]
162202 pub fn from_raw (
163- introduction_node_id : PublicKey , blinding_point : PublicKey , blinded_hops : Vec < BlindedHop >
203+ introduction_node_id : PublicKey , blinding_point : PublicKey , blinded_hops : Vec < BlindedHop > ,
204+ payinfo : BlindedPayInfo
164205 ) -> Self {
165- Self ( BlindedPath {
166- introduction_node : IntroductionNode :: NodeId ( introduction_node_id) ,
167- blinding_point,
168- blinded_hops,
169- } )
206+ Self {
207+ inner_path : BlindedPath {
208+ introduction_node : IntroductionNode :: NodeId ( introduction_node_id) ,
209+ blinding_point,
210+ blinded_hops,
211+ } ,
212+ payinfo
213+ }
170214 }
171215
172216 #[ cfg( test) ]
173217 pub fn clear_blinded_hops ( & mut self ) {
174- self . 0 . blinded_hops . clear ( )
218+ self . inner_path . blinded_hops . clear ( )
175219 }
176220}
177221
0 commit comments