@@ -1263,7 +1263,6 @@ fn lsps2_client_service_integration() {
12631263 min_channel_lifetime : 100 ,
12641264 min_channel_opening_fee_msat : 0 ,
12651265 max_client_to_self_delay : 1024 ,
1266- client_trusts_lsp : false ,
12671266 } ;
12681267
12691268 let service_config = random_config ( true ) ;
@@ -1409,7 +1408,6 @@ fn lsps2_client_trusts_lsp() {
14091408 min_channel_lifetime : 100 ,
14101409 min_channel_opening_fee_msat : 0 ,
14111410 max_client_to_self_delay : 1024 ,
1412- client_trusts_lsp : true ,
14131411 } ;
14141412
14151413 let service_config = random_config ( true ) ;
@@ -1418,7 +1416,7 @@ fn lsps2_client_trusts_lsp() {
14181416 service_builder. set_liquidity_provider_lsps2 ( lsps2_service_config) ;
14191417 let service_node = service_builder. build ( ) . unwrap ( ) ;
14201418 service_node. start ( ) . unwrap ( ) ;
1421-
1419+ service_node . set_lsps2_client_trusts_lsp ( true ) . unwrap ( ) ;
14221420 let service_node_id = service_node. node_id ( ) ;
14231421 let service_addr = service_node. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ;
14241422
@@ -1530,6 +1528,119 @@ fn lsps2_client_trusts_lsp() {
15301528 assert ! ( funding_tx_found, "Funding transaction should be broadcast after the client claims it" ) ;
15311529}
15321530
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+
15331644#[ test]
15341645fn lsps2_lsp_trusts_client_but_client_does_not_claim ( ) {
15351646 let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
@@ -1551,7 +1662,6 @@ fn lsps2_lsp_trusts_client_but_client_does_not_claim() {
15511662 min_channel_lifetime : 100 ,
15521663 min_channel_opening_fee_msat : 0 ,
15531664 max_client_to_self_delay : 1024 ,
1554- client_trusts_lsp : false ,
15551665 } ;
15561666
15571667 let service_config = random_config ( true ) ;
0 commit comments