@@ -1263,7 +1263,6 @@ fn lsps2_client_service_integration() {
1263
1263
min_channel_lifetime : 100 ,
1264
1264
min_channel_opening_fee_msat : 0 ,
1265
1265
max_client_to_self_delay : 1024 ,
1266
- client_trusts_lsp : false ,
1267
1266
} ;
1268
1267
1269
1268
let service_config = random_config ( true ) ;
@@ -1409,7 +1408,6 @@ fn lsps2_client_trusts_lsp() {
1409
1408
min_channel_lifetime : 100 ,
1410
1409
min_channel_opening_fee_msat : 0 ,
1411
1410
max_client_to_self_delay : 1024 ,
1412
- client_trusts_lsp : true ,
1413
1411
} ;
1414
1412
1415
1413
let service_config = random_config ( true ) ;
@@ -1418,7 +1416,7 @@ fn lsps2_client_trusts_lsp() {
1418
1416
service_builder. set_liquidity_provider_lsps2 ( lsps2_service_config) ;
1419
1417
let service_node = service_builder. build ( ) . unwrap ( ) ;
1420
1418
service_node. start ( ) . unwrap ( ) ;
1421
-
1419
+ service_node . set_lsps2_client_trusts_lsp ( true ) . unwrap ( ) ;
1422
1420
let service_node_id = service_node. node_id ( ) ;
1423
1421
let service_addr = service_node. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1424
1422
@@ -1530,6 +1528,119 @@ fn lsps2_client_trusts_lsp() {
1530
1528
assert ! ( funding_tx_found, "Funding transaction should be broadcast after the client claims it" ) ;
1531
1529
}
1532
1530
1531
+ #[ test]
1532
+ fn lsps2_in_flight_under_attack_switch ( ) {
1533
+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
1534
+
1535
+ let esplora_url = format ! ( "http://{}" , electrsd. esplora_url. as_ref( ) . unwrap( ) ) ;
1536
+
1537
+ let sync_config = EsploraSyncConfig { background_sync_config : None } ;
1538
+
1539
+ // Setup three nodes: service, client, and payer
1540
+ let channel_opening_fee_ppm = 10_000 ;
1541
+ let channel_over_provisioning_ppm = 100_000 ;
1542
+ let lsps2_service_config = LSPS2ServiceConfig {
1543
+ require_token : None ,
1544
+ advertise_service : false ,
1545
+ channel_opening_fee_ppm,
1546
+ channel_over_provisioning_ppm,
1547
+ max_payment_size_msat : 1_000_000_000 ,
1548
+ min_payment_size_msat : 0 ,
1549
+ min_channel_lifetime : 100 ,
1550
+ min_channel_opening_fee_msat : 0 ,
1551
+ max_client_to_self_delay : 1024 ,
1552
+ } ;
1553
+
1554
+ let service_config = random_config ( true ) ;
1555
+ setup_builder ! ( service_builder, service_config. node_config) ;
1556
+ service_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1557
+ service_builder. set_liquidity_provider_lsps2 ( lsps2_service_config) ;
1558
+ let service_node = service_builder. build ( ) . unwrap ( ) ;
1559
+ service_node. start ( ) . unwrap ( ) ;
1560
+
1561
+ let service_node_id = service_node. node_id ( ) ;
1562
+ let service_addr = service_node. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1563
+
1564
+ let client_config = random_config ( true ) ;
1565
+ setup_builder ! ( client_builder, client_config. node_config) ;
1566
+ client_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1567
+ client_builder. set_liquidity_source_lsps2 ( service_node_id, service_addr. clone ( ) , None ) ;
1568
+ let client_node = client_builder. build ( ) . unwrap ( ) ;
1569
+ client_node. start ( ) . unwrap ( ) ;
1570
+
1571
+ let payer_config = random_config ( true ) ;
1572
+ setup_builder ! ( payer_builder, payer_config. node_config) ;
1573
+ payer_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1574
+ let payer_node = payer_builder. build ( ) . unwrap ( ) ;
1575
+ payer_node. start ( ) . unwrap ( ) ;
1576
+
1577
+ let service_addr_onchain = service_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1578
+ let client_addr_onchain = client_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1579
+ let payer_addr_onchain = payer_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1580
+
1581
+ let premine_amount_sat = 10_000_000 ;
1582
+
1583
+ premine_and_distribute_funds (
1584
+ & bitcoind. client ,
1585
+ & electrsd. client ,
1586
+ vec ! [ service_addr_onchain, client_addr_onchain, payer_addr_onchain] ,
1587
+ Amount :: from_sat ( premine_amount_sat) ,
1588
+ ) ;
1589
+ service_node. sync_wallets ( ) . unwrap ( ) ;
1590
+ client_node. sync_wallets ( ) . unwrap ( ) ;
1591
+ payer_node. sync_wallets ( ) . unwrap ( ) ;
1592
+ println ! ( "Premine complete!" ) ;
1593
+ // Open a channel payer -> service that will allow paying the JIT invoice
1594
+ open_channel ( & payer_node, & service_node, 5_000_000 , false , & electrsd) ;
1595
+
1596
+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) ;
1597
+ service_node. sync_wallets ( ) . unwrap ( ) ;
1598
+ payer_node. sync_wallets ( ) . unwrap ( ) ;
1599
+ expect_channel_ready_event ! ( payer_node, service_node. node_id( ) ) ;
1600
+ expect_channel_ready_event ! ( service_node, payer_node. node_id( ) ) ;
1601
+
1602
+ let initial_mempool_size = bitcoind. client . get_raw_mempool ( ) . unwrap ( ) . 0 . len ( ) ;
1603
+
1604
+ let invoice_description =
1605
+ Bolt11InvoiceDescription :: Direct ( Description :: new ( String :: from ( "asdf" ) ) . unwrap ( ) ) ;
1606
+ let jit_amount_msat = 100_000_000 ;
1607
+
1608
+ println ! ( "Generating JIT invoice!" ) ;
1609
+ let jit_invoice = client_node
1610
+ . bolt11_payment ( )
1611
+ . receive_via_jit_channel ( jit_amount_msat, & invoice_description. into ( ) , 1024 , None )
1612
+ . unwrap ( ) ;
1613
+
1614
+ // Have the payer_node pay the invoice, thereby triggering channel open service_node -> client_node.
1615
+ println ! ( "Paying JIT invoice!" ) ;
1616
+ let _payment_id = payer_node. bolt11_payment ( ) . send ( & jit_invoice, None ) . unwrap ( ) ;
1617
+
1618
+ // Switch trust mode immediately after payment is sent, before events are processed.
1619
+ // This simulates the LSP going into "under-attack" mode.
1620
+ println ! ( "Switching trust mode on LSP during in-flight JIT channel opening." ) ;
1621
+ service_node. set_lsps2_client_trusts_lsp ( true ) . unwrap ( ) ;
1622
+
1623
+ expect_channel_pending_event ! ( service_node, client_node. node_id( ) ) ;
1624
+ expect_channel_ready_event ! ( service_node, client_node. node_id( ) ) ;
1625
+ expect_channel_pending_event ! ( client_node, service_node. node_id( ) ) ;
1626
+ expect_channel_ready_event ! ( client_node, service_node. node_id( ) ) ;
1627
+
1628
+ println ! ( "Waiting for funding transaction to be broadcast..." ) ;
1629
+ let mut funding_tx_found = false ;
1630
+ for _ in 0 ..500 {
1631
+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 100 ) ) ;
1632
+ let current_mempool = bitcoind. client . get_raw_mempool ( ) . unwrap ( ) ;
1633
+ if current_mempool. 0 . len ( ) > initial_mempool_size {
1634
+ funding_tx_found = true ;
1635
+ break ;
1636
+ }
1637
+ }
1638
+ assert ! (
1639
+ funding_tx_found,
1640
+ "Funding transaction should be broadcast immediately as the JIT process started before the trust switch"
1641
+ ) ;
1642
+ }
1643
+
1533
1644
#[ test]
1534
1645
fn lsps2_lsp_trusts_client_but_client_does_not_claim ( ) {
1535
1646
let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
@@ -1551,7 +1662,6 @@ fn lsps2_lsp_trusts_client_but_client_does_not_claim() {
1551
1662
min_channel_lifetime : 100 ,
1552
1663
min_channel_opening_fee_msat : 0 ,
1553
1664
max_client_to_self_delay : 1024 ,
1554
- client_trusts_lsp : false ,
1555
1665
} ;
1556
1666
1557
1667
let service_config = random_config ( true ) ;
0 commit comments