@@ -42,7 +42,7 @@ use lightning_liquidity::utils::time::{DefaultTimeProvider, TimeProvider};
4242use lightning_liquidity:: { LiquidityClientConfig , LiquidityManagerSync , LiquidityServiceConfig } ;
4343
4444use lightning:: blinded_path:: payment:: {
45- Bolt12OfferContext , PaymentConstraints , PaymentContext , ReceiveTlvs ,
45+ BlindedPaymentPath , Bolt12OfferContext , PaymentConstraints , PaymentContext , ReceiveTlvs ,
4646} ;
4747use lightning:: blinded_path:: NodeIdLookUp ;
4848use lightning:: ln:: channelmanager:: { InterceptId , MIN_FINAL_CLTV_EXPIRY_DELTA } ;
@@ -116,6 +116,42 @@ impl Router for FailingRouter {
116116 }
117117}
118118
119+ struct FallbackBeforeMetadataRouter ;
120+
121+ impl Router for FallbackBeforeMetadataRouter {
122+ fn find_route (
123+ & self , _payer : & PublicKey , _route_params : & RouteParameters ,
124+ _first_hops : Option < & [ & lightning:: ln:: channel_state:: ChannelDetails ] > ,
125+ _inflight_htlcs : InFlightHtlcs ,
126+ ) -> Result < Route , & ' static str > {
127+ Err ( "fallback-before-metadata test router" )
128+ }
129+
130+ fn create_blinded_payment_paths <
131+ T : bitcoin:: secp256k1:: Signing + bitcoin:: secp256k1:: Verification ,
132+ > (
133+ & self , recipient : PublicKey , local_node_receive_key : ReceiveAuthKey ,
134+ _first_hops : Vec < lightning:: ln:: channel_state:: ChannelDetails > , tlvs : ReceiveTlvs ,
135+ _amount_msats : Option < u64 > , secp_ctx : & Secp256k1 < T > ,
136+ ) -> Result < Vec < BlindedPaymentPath > , ( ) > {
137+ if tlvs. payment_context . payment_metadata ( ) . is_some ( ) {
138+ return Err ( ( ) ) ;
139+ }
140+
141+ BlindedPaymentPath :: new (
142+ & [ ] ,
143+ recipient,
144+ local_node_receive_key,
145+ tlvs,
146+ u64:: MAX ,
147+ MIN_FINAL_CLTV_EXPIRY_DELTA ,
148+ & RandomBytes :: new ( [ 44 ; 32 ] ) ,
149+ secp_ctx,
150+ )
151+ . map ( |path| vec ! [ path] )
152+ }
153+ }
154+
119155#[ derive( Clone , Copy ) ]
120156struct TestBolt12PaymentMetadataDecoder ;
121157
@@ -593,7 +629,7 @@ fn channel_open_failed_releases_intercepted_htlcs() {
593629
594630 let intercept_scid = service_node. node . get_intercept_scid ( ) ;
595631 let user_channel_id = 42u128 ;
596- let cltv_expiry_delta: u32 = 144 ;
632+ let cltv_expiry_delta: u16 = 144 ;
597633 let payment_size_msat = Some ( 1_000_000 ) ;
598634 let fee_base_msat: u64 = 1_000 ;
599635
@@ -2198,7 +2234,7 @@ fn bolt12_lsps2_compact_message_path_test() {
21982234 let intercepted_msg = events
21992235 . into_iter ( )
22002236 . find_map ( |e| match e {
2201- Event :: OnionMessageIntercepted { next_hop, message } => {
2237+ Event :: OnionMessageIntercepted { next_hop, message, .. } => {
22022238 assert_eq ! ( next_hop, NextMessageHop :: ShortChannelId ( intercept_scid) ) ;
22032239 Some ( message)
22042240 } ,
@@ -3186,7 +3222,7 @@ fn async_payment_via_lsps2_jit_channel() {
31863222 let payment_metadata =
31873223 lsps2_bolt12_payment_metadata ( service_node_id, intercept_scid, cltv_expiry_delta) ;
31883224 let lsps2_router = Arc :: new ( LSPS2BOLT12Router :: new_with_payment_metadata_decoder (
3189- FailingRouter :: new ( ) ,
3225+ FallbackBeforeMetadataRouter ,
31903226 Arc :: new ( RandomBytes :: new ( [ 43 ; 32 ] ) ) ,
31913227 TestBolt12PaymentMetadataDecoder ,
31923228 ) ) ;
@@ -3219,6 +3255,30 @@ fn async_payment_via_lsps2_jit_channel() {
32193255 . blinded_paths_for_async_recipient ( recipient_id. clone ( ) , None )
32203256 . unwrap ( ) ;
32213257 client_node. inner . node . set_paths_to_static_invoice_server ( inv_server_paths) . unwrap ( ) ;
3258+
3259+ // The path setup above triggers an automatic async-offer refresh before the LSPS2 metadata
3260+ // has been attached. Even if the inner router could build a fallback path, we must not upload
3261+ // a static invoice for the LSPS2 JIT flow until the metadata-derived intercept-SCID path is
3262+ // available.
3263+ while let Some ( msg) =
3264+ client_node. inner . onion_messenger . next_onion_message_for_peer ( service_node_id)
3265+ {
3266+ service_node. inner . onion_messenger . handle_onion_message ( client_node_id, & msg) ;
3267+ }
3268+ while let Some ( msg) =
3269+ service_node. inner . onion_messenger . next_onion_message_for_peer ( client_node_id)
3270+ {
3271+ client_node. inner . onion_messenger . handle_onion_message ( service_node_id, & msg) ;
3272+ }
3273+ assert ! (
3274+ client_node. inner. onion_messenger. next_onion_message_for_peer( service_node_id) . is_none( ) ,
3275+ "client must not upload a static invoice before LSPS2 metadata is available"
3276+ ) ;
3277+ assert ! (
3278+ service_node. inner. node. get_and_clear_pending_events( ) . is_empty( ) ,
3279+ "service must not receive a static invoice before LSPS2 metadata is available"
3280+ ) ;
3281+
32223282 client_node
32233283 . inner
32243284 . node
@@ -3371,7 +3431,7 @@ fn async_payment_via_lsps2_jit_channel() {
33713431 . into_inner ( )
33723432 . into_iter ( )
33733433 . filter_map ( |e| match e {
3374- Event :: OnionMessageIntercepted { next_hop, message } => {
3434+ Event :: OnionMessageIntercepted { next_hop, message, .. } => {
33753435 assert_eq ! ( next_hop, NextMessageHop :: NodeId ( client_node_id) ) ;
33763436 Some ( message)
33773437 } ,
0 commit comments