Skip to content

Commit b6858cf

Browse files
committed
lsps2: Test multi-LSP BOLT12 selection
Extend the order-independent fee-selection scenario through a real BOLT12 payment. Also prove that BOLT11 consumption and BOLT12 response handling share the same replenished lease pool. Co-Authored-By: HAL 9000
1 parent 9c63f22 commit b6858cf

1 file changed

Lines changed: 62 additions & 2 deletions

File tree

tests/integration_tests_rust.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4486,17 +4486,18 @@ async fn lsps2_multi_lsp_rejects_fees_above_limit() {
44864486
async fn do_lsps2_multi_lsp_picks_cheapest(
44874487
reverse_order: bool, max_total_lsp_fee_limit_msat: Option<u64>,
44884488
) {
4489-
let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd();
4489+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
44904490
let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap());
44914491

44924492
let mut sync_config = EsploraSyncConfig::default();
44934493
sync_config.background_sync_config = None;
44944494

44954495
// Cheap LSP: 10_000 ppm.
4496+
let cheap_opening_fee_ppm = 10_000;
44964497
let cheap_cfg = LSPS2ServiceConfig {
44974498
require_token: None,
44984499
advertise_service: false,
4499-
channel_opening_fee_ppm: 10_000,
4500+
channel_opening_fee_ppm: cheap_opening_fee_ppm,
45004501
channel_over_provisioning_ppm: 100_000,
45014502
max_payment_size_msat: 1_000_000_000,
45024503
min_payment_size_msat: 0,
@@ -4553,12 +4554,47 @@ async fn do_lsps2_multi_lsp_picks_cheapest(
45534554
let client = client_builder.build(client_config.node_entropy.into()).unwrap();
45544555
client.start().unwrap();
45554556

4557+
let payer_config = random_config();
4558+
setup_builder!(payer_builder, payer_config.node_config);
4559+
payer_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config));
4560+
let payer = payer_builder.build(payer_config.node_entropy.into()).unwrap();
4561+
payer.start().unwrap();
4562+
4563+
let client_addr = client.listening_addresses().unwrap().first().unwrap().clone();
4564+
payer.connect(client.node_id(), client_addr, false).unwrap();
4565+
4566+
let cheap_onchain_addr = cheap.onchain_payment().new_address().unwrap();
4567+
let client_onchain_addr = client.onchain_payment().new_address().unwrap();
4568+
let payer_onchain_addr = payer.onchain_payment().new_address().unwrap();
4569+
premine_and_distribute_funds(
4570+
&bitcoind.client,
4571+
&electrsd.client,
4572+
vec![cheap_onchain_addr, client_onchain_addr, payer_onchain_addr],
4573+
Amount::from_sat(10_000_000),
4574+
)
4575+
.await;
4576+
cheap.sync_wallets().unwrap();
4577+
client.sync_wallets().unwrap();
4578+
payer.sync_wallets().unwrap();
4579+
4580+
open_channel(&payer, &cheap, 5_000_000, true, &electrsd).await;
4581+
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;
4582+
cheap.sync_wallets().unwrap();
4583+
payer.sync_wallets().unwrap();
4584+
expect_channel_ready_event!(payer, cheap.node_id());
4585+
expect_channel_ready_event!(cheap, payer.node_id());
4586+
while payer.status().latest_node_announcement_broadcast_timestamp.is_none() {
4587+
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
4588+
}
4589+
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
4590+
45564591
let invoice_description =
45574592
Bolt11InvoiceDescription::Direct(Description::new(String::from("asdf")).unwrap()).into();
45584593
let jit_invoice_result =
45594594
client.bolt11_payment().receive_via_jit_channel(100_000_000, &invoice_description, 1024);
45604595
if max_total_lsp_fee_limit_msat.is_some() {
45614596
assert!(matches!(jit_invoice_result, Err(NodeError::LiquidityFeeTooHigh)));
4597+
payer.stop().unwrap();
45624598
client.stop().unwrap();
45634599
cheap.stop().unwrap();
45644600
expensive.stop().unwrap();
@@ -4576,6 +4612,30 @@ async fn do_lsps2_multi_lsp_picks_cheapest(
45764612
let route_hint_src = first_hop.expect("route hint should have at least one hop").src_node_id;
45774613
assert_eq!(route_hint_src, cheap_id, "expected cheaper LSP to be selected.");
45784614

4615+
// Consuming the BOLT11 lease schedules a replacement. The BOLT12 flow shares that cache and
4616+
// must retain the same cheapest-LSP selection regardless of registration order.
4617+
let payment_amount_msat = 100_000_000;
4618+
let offer =
4619+
client.bolt12_payment().receive(payment_amount_msat, "multi LSP", None, None).unwrap();
4620+
let payment_id = payer.bolt12_payment().send(&offer, None, None, None).unwrap();
4621+
4622+
expect_channel_pending_event!(cheap, client.node_id());
4623+
expect_channel_ready_event!(cheap, client.node_id());
4624+
expect_event!(cheap, PaymentForwarded);
4625+
expect_channel_pending_event!(client, cheap.node_id());
4626+
expect_channel_ready_event!(client, cheap.node_id());
4627+
expect_payment_successful_event!(payer, Some(payment_id), None);
4628+
let fee_msat = payment_amount_msat * cheap_opening_fee_ppm as u64 / 1_000_000;
4629+
let receiver_payment_id =
4630+
expect_payment_received_event!(client, payment_amount_msat - fee_msat).unwrap();
4631+
match client.payment(&receiver_payment_id).unwrap().kind {
4632+
PaymentKind::Bolt12Offer { counterparty_skimmed_fee_msat, .. } => {
4633+
assert_eq!(counterparty_skimmed_fee_msat, Some(fee_msat));
4634+
},
4635+
_ => panic!("Unexpected payment kind"),
4636+
}
4637+
4638+
payer.stop().unwrap();
45794639
client.stop().unwrap();
45804640
cheap.stop().unwrap();
45814641
expensive.stop().unwrap();

0 commit comments

Comments
 (0)