@@ -20,11 +20,12 @@ use lightning::blinded_path::message::{
2020 BlindedMessagePath , MessageContext , MessageForwardNode , OffersContext ,
2121} ;
2222use lightning:: blinded_path:: payment:: {
23- BlindedPaymentPath , Bolt12OfferContext , ForwardTlvs , PaymentConstraints , PaymentContext ,
24- PaymentForwardNode , PaymentRelay , ReceiveTlvs ,
23+ AsyncBolt12OfferContext , BlindedPaymentPath , Bolt12OfferContext , ForwardTlvs ,
24+ PaymentConstraints , PaymentContext , PaymentForwardNode , PaymentRelay , ReceiveTlvs ,
2525} ;
2626use lightning:: ln:: channel_state:: ChannelDetails ;
2727use lightning:: ln:: channelmanager:: { PaymentId , MIN_FINAL_CLTV_EXPIRY_DELTA } ;
28+ use lightning:: offers:: nonce:: Nonce ;
2829use lightning:: offers:: offer:: OfferId ;
2930use lightning:: onion_message:: messenger:: { Destination , MessageRouter , OnionMessagePath } ;
3031use lightning:: routing:: router:: { InFlightHtlcs , Route , RouteParameters , Router } ;
@@ -61,6 +62,7 @@ pub struct LSPS2BOLT12Router<R: Router, MR: MessageRouter, ES: EntropySource + S
6162 inner_message_router : MR ,
6263 entropy_source : ES ,
6364 offer_to_invoice_params : Mutex < HashMap < [ u8 ; 32 ] , LSPS2Bolt12InvoiceParameters > > ,
65+ nonce_to_invoice_params : Mutex < HashMap < [ u8 ; Nonce :: LENGTH ] , LSPS2Bolt12InvoiceParameters > > ,
6466}
6567
6668impl < R : Router , MR : MessageRouter , ES : EntropySource + Send + Sync > LSPS2BOLT12Router < R , MR , ES > {
@@ -71,6 +73,7 @@ impl<R: Router, MR: MessageRouter, ES: EntropySource + Send + Sync> LSPS2BOLT12R
7173 inner_message_router,
7274 entropy_source,
7375 offer_to_invoice_params : Mutex :: new ( new_hash_map ( ) ) ,
76+ nonce_to_invoice_params : Mutex :: new ( new_hash_map ( ) ) ,
7477 }
7578 }
7679
@@ -86,22 +89,50 @@ impl<R: Router, MR: MessageRouter, ES: EntropySource + Send + Sync> LSPS2BOLT12R
8689 self . offer_to_invoice_params . lock ( ) . unwrap ( ) . remove ( & offer_id. 0 )
8790 }
8891
89- /// Clears all LSPS2 parameters previously registered via [`Self::register_offer`].
92+ /// Registers LSPS2 parameters to be used when generating blinded payment paths for an async
93+ /// BOLT12 offer identified by its `offer_nonce`.
94+ ///
95+ /// This is the async-offer counterpart to [`Self::register_offer`], used for
96+ /// [`PaymentContext::AsyncBolt12Offer`] contexts where the offer is identified by its nonce
97+ /// rather than its [`OfferId`].
98+ pub fn register_offer_nonce (
99+ & self , offer_nonce : Nonce , invoice_params : LSPS2Bolt12InvoiceParameters ,
100+ ) -> Option < LSPS2Bolt12InvoiceParameters > {
101+ let mut key = [ 0u8 ; Nonce :: LENGTH ] ;
102+ key. copy_from_slice ( offer_nonce. as_slice ( ) ) ;
103+ self . nonce_to_invoice_params . lock ( ) . unwrap ( ) . insert ( key, invoice_params)
104+ }
105+
106+ /// Removes any previously registered LSPS2 parameters for `offer_nonce`.
107+ pub fn unregister_offer_nonce (
108+ & self , offer_nonce : & Nonce ,
109+ ) -> Option < LSPS2Bolt12InvoiceParameters > {
110+ let mut key = [ 0u8 ; Nonce :: LENGTH ] ;
111+ key. copy_from_slice ( offer_nonce. as_slice ( ) ) ;
112+ self . nonce_to_invoice_params . lock ( ) . unwrap ( ) . remove ( & key)
113+ }
114+
115+ /// Clears all LSPS2 parameters previously registered via [`Self::register_offer`] and
116+ /// [`Self::register_offer_nonce`].
90117 pub fn clear_registered_offers ( & self ) {
91118 self . offer_to_invoice_params . lock ( ) . unwrap ( ) . clear ( ) ;
119+ self . nonce_to_invoice_params . lock ( ) . unwrap ( ) . clear ( ) ;
92120 }
93121
94122 fn registered_lsps2_params (
95123 & self , payment_context : & PaymentContext ,
96124 ) -> Option < LSPS2Bolt12InvoiceParameters > {
97- // We intentionally only match `Bolt12Offer` here and not `AsyncBolt12Offer`, as LSPS2
98- // JIT channels are not applicable to async (always-online) BOLT12 offer flows.
99- let Bolt12OfferContext { offer_id, .. } = match payment_context {
100- PaymentContext :: Bolt12Offer ( context) => context,
101- _ => return None ,
102- } ;
103-
104- self . offer_to_invoice_params . lock ( ) . unwrap ( ) . get ( & offer_id. 0 ) . copied ( )
125+ match payment_context {
126+ PaymentContext :: Bolt12Offer ( Bolt12OfferContext { offer_id, .. } ) => {
127+ self . offer_to_invoice_params . lock ( ) . unwrap ( ) . get ( & offer_id. 0 ) . copied ( )
128+ } ,
129+ PaymentContext :: AsyncBolt12Offer ( AsyncBolt12OfferContext { offer_nonce } ) => {
130+ let mut key = [ 0u8 ; Nonce :: LENGTH ] ;
131+ key. copy_from_slice ( offer_nonce. as_slice ( ) ) ;
132+ self . nonce_to_invoice_params . lock ( ) . unwrap ( ) . get ( & key) . copied ( )
133+ } ,
134+ _ => None ,
135+ }
105136 }
106137}
107138
@@ -212,14 +243,18 @@ impl<R: Router, MR: MessageRouter, ES: EntropySource + Send + Sync> MessageRoute
212243 // is only used for routing InvoiceRequests, not for payment interception.
213244 let peers = match & context {
214245 MessageContext :: Offers ( OffersContext :: InvoiceRequest { .. } ) => {
215- let params = self . offer_to_invoice_params . lock ( ) . unwrap ( ) ;
246+ let offer_params = self . offer_to_invoice_params . lock ( ) . unwrap ( ) ;
247+ let nonce_params = self . nonce_to_invoice_params . lock ( ) . unwrap ( ) ;
216248 peers
217249 . into_iter ( )
218250 . map ( |mut peer| {
219- if let Some ( p) =
220- params. values ( ) . find ( |p| p. counterparty_node_id == peer. node_id )
221- {
222- peer. short_channel_id = Some ( p. intercept_scid ) ;
251+ let scid = offer_params
252+ . values ( )
253+ . chain ( nonce_params. values ( ) )
254+ . find ( |p| p. counterparty_node_id == peer. node_id )
255+ . map ( |p| p. intercept_scid ) ;
256+ if let Some ( scid) = scid {
257+ peer. short_channel_id = Some ( scid) ;
223258 }
224259 peer
225260 } )
0 commit comments