Skip to content

Commit eeff163

Browse files
committed
f - Cover LSPS2 async invoice gating
Assert no static invoice is uploaded before LSPS2 metadata is ready. Keep LSPS2 integration tests compiling with current upstream types. Co-Authored-By: HAL 9000
1 parent e50eec0 commit eeff163

1 file changed

Lines changed: 65 additions & 5 deletions

File tree

lightning-liquidity/tests/lsps2_integration_tests.rs

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use lightning_liquidity::utils::time::{DefaultTimeProvider, TimeProvider};
4242
use lightning_liquidity::{LiquidityClientConfig, LiquidityManagerSync, LiquidityServiceConfig};
4343

4444
use lightning::blinded_path::payment::{
45-
Bolt12OfferContext, PaymentConstraints, PaymentContext, ReceiveTlvs,
45+
BlindedPaymentPath, Bolt12OfferContext, PaymentConstraints, PaymentContext, ReceiveTlvs,
4646
};
4747
use lightning::blinded_path::NodeIdLookUp;
4848
use 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)]
120156
struct 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

Comments
 (0)