@@ -1799,6 +1799,158 @@ fn lsps2_client_service_integration() {
17991799 assert_eq ! ( channel_value_sats, expected_channel_size_sat) ;
18001800}
18011801
1802+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
1803+ async fn lsps2_client_service_integration_manual_event_request ( ) {
1804+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
1805+
1806+ let esplora_url = format ! ( "http://{}" , electrsd. esplora_url. as_ref( ) . unwrap( ) ) ;
1807+
1808+ let sync_config = EsploraSyncConfig { background_sync_config : None } ;
1809+
1810+ // Setup three nodes: service, client, and payer
1811+ let channel_opening_fee_ppm = 10_000 ;
1812+ let channel_over_provisioning_ppm = 100_000 ;
1813+ let lsps2_service_config = LSPS2ServiceConfig {
1814+ require_token : None ,
1815+ advertise_service : false ,
1816+ channel_opening_fee_ppm,
1817+ channel_over_provisioning_ppm,
1818+ max_payment_size_msat : 1_000_000_000 ,
1819+ min_payment_size_msat : 0 ,
1820+ min_channel_lifetime : 100 ,
1821+ min_channel_opening_fee_msat : 0 ,
1822+ max_client_to_self_delay : 1024 ,
1823+ } ;
1824+
1825+ let service_config = random_config ( true ) ;
1826+ setup_builder ! ( service_builder, service_config. node_config) ;
1827+ service_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1828+ service_builder. set_liquidity_provider_lsps2 ( lsps2_service_config) ;
1829+ service_builder. set_manually_handle_liquidity_requests ( true ) ;
1830+ let service_node = Arc :: new ( service_builder. build ( ) . unwrap ( ) ) ;
1831+ service_node. start ( ) . unwrap ( ) ;
1832+
1833+ let service_node_id = service_node. node_id ( ) ;
1834+ let service_addr = service_node. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1835+
1836+ let client_config = random_config ( true ) ;
1837+ setup_builder ! ( client_builder, client_config. node_config) ;
1838+ client_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1839+ client_builder. set_liquidity_source_lsps2 ( service_node_id, service_addr, None ) ;
1840+ client_builder. set_manually_handle_liquidity_requests ( true ) ;
1841+ let client_node = Arc :: new ( client_builder. build ( ) . unwrap ( ) ) ;
1842+ client_node. start ( ) . unwrap ( ) ;
1843+
1844+ let payer_config = random_config ( true ) ;
1845+ setup_builder ! ( payer_builder, payer_config. node_config) ;
1846+ payer_builder. set_chain_source_esplora ( esplora_url. clone ( ) , Some ( sync_config) ) ;
1847+ let payer_node = payer_builder. build ( ) . unwrap ( ) ;
1848+ payer_node. start ( ) . unwrap ( ) ;
1849+
1850+ let service_addr = service_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1851+ let client_addr = client_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1852+ let payer_addr = payer_node. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1853+
1854+ let premine_amount_sat = 10_000_000 ;
1855+
1856+ premine_and_distribute_funds (
1857+ & bitcoind. client ,
1858+ & electrsd. client ,
1859+ vec ! [ service_addr, client_addr, payer_addr] ,
1860+ Amount :: from_sat ( premine_amount_sat) ,
1861+ ) ;
1862+ service_node. sync_wallets ( ) . unwrap ( ) ;
1863+ client_node. sync_wallets ( ) . unwrap ( ) ;
1864+ payer_node. sync_wallets ( ) . unwrap ( ) ;
1865+
1866+ // Spawn tasks to manually handle liquidity events by processing them with defaults
1867+ let node = Arc :: clone ( & service_node) ;
1868+ let service_handle = tokio:: spawn ( async move {
1869+ loop {
1870+ let event = node. liquidity_next_event_async ( ) . await . unwrap ( ) ;
1871+ node. liquidity_process_event_defaults ( event) . await . unwrap ( ) ;
1872+ }
1873+ } ) ;
1874+
1875+ let node = Arc :: clone ( & client_node) ;
1876+ let client_handle = tokio:: spawn ( async move {
1877+ loop {
1878+ let event = node. liquidity_next_event_async ( ) . await . unwrap ( ) ;
1879+ node. liquidity_process_event_defaults ( event) . await . unwrap ( ) ;
1880+ }
1881+ } ) ;
1882+
1883+ // Open a channel payer -> service that will allow paying the JIT invoice
1884+ println ! ( "Opening channel payer_node -> service_node!" ) ;
1885+ open_channel ( & payer_node, & service_node, 5_000_000 , false , & electrsd) ;
1886+
1887+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) ;
1888+ service_node. sync_wallets ( ) . unwrap ( ) ;
1889+ payer_node. sync_wallets ( ) . unwrap ( ) ;
1890+
1891+ expect_channel_ready_event ! ( payer_node, service_node. node_id( ) ) ;
1892+ expect_channel_ready_event ! ( service_node, payer_node. node_id( ) ) ;
1893+
1894+ let invoice_description =
1895+ Bolt11InvoiceDescription :: Direct ( Description :: new ( String :: from ( "asdf" ) ) . unwrap ( ) ) ;
1896+ let jit_amount_msat = 100_000_000 ;
1897+
1898+ println ! ( "Generating JIT invoice!" ) ;
1899+ let jit_invoice = client_node
1900+ . bolt11_payment ( )
1901+ . receive_via_jit_channel ( jit_amount_msat, & invoice_description. into ( ) , 1024 , None )
1902+ . unwrap ( ) ;
1903+
1904+ // Have the payer_node pay the invoice, therby triggering channel open service_node -> client_node.
1905+ println ! ( "Paying JIT invoice!" ) ;
1906+ let payment_id = payer_node. bolt11_payment ( ) . send ( & jit_invoice, None ) . unwrap ( ) ;
1907+
1908+ expect_channel_pending_event ! ( service_node, client_node. node_id( ) ) ;
1909+ expect_channel_ready_event ! ( service_node, client_node. node_id( ) ) ;
1910+ expect_event ! ( service_node, PaymentForwarded ) ;
1911+ expect_channel_pending_event ! ( client_node, service_node. node_id( ) ) ;
1912+ expect_channel_ready_event ! ( client_node, service_node. node_id( ) ) ;
1913+
1914+ let service_fee_msat = ( jit_amount_msat * channel_opening_fee_ppm as u64 ) / 1_000_000 ;
1915+ let expected_received_amount_msat = jit_amount_msat - service_fee_msat;
1916+ expect_payment_successful_event ! ( payer_node, Some ( payment_id) , None ) ;
1917+ let client_payment_id =
1918+ expect_payment_received_event ! ( client_node, expected_received_amount_msat) . unwrap ( ) ;
1919+ let client_payment = client_node. payment ( & client_payment_id) . unwrap ( ) ;
1920+ match client_payment. kind {
1921+ PaymentKind :: Bolt11Jit { counterparty_skimmed_fee_msat, .. } => {
1922+ assert_eq ! ( counterparty_skimmed_fee_msat, Some ( service_fee_msat) ) ;
1923+ } ,
1924+ _ => panic ! ( "Unexpected payment kind" ) ,
1925+ }
1926+
1927+ let expected_channel_overprovisioning_msat =
1928+ ( expected_received_amount_msat * channel_over_provisioning_ppm as u64 ) / 1_000_000 ;
1929+ let expected_channel_size_sat =
1930+ ( expected_received_amount_msat + expected_channel_overprovisioning_msat) / 1000 ;
1931+ let channel_value_sats = client_node. list_channels ( ) . first ( ) . unwrap ( ) . channel_value_sats ;
1932+ assert_eq ! ( channel_value_sats, expected_channel_size_sat) ;
1933+
1934+ println ! ( "Generating regular invoice!" ) ;
1935+ let invoice_description =
1936+ Bolt11InvoiceDescription :: Direct ( Description :: new ( String :: from ( "asdf" ) ) . unwrap ( ) ) . into ( ) ;
1937+ let amount_msat = 5_000_000 ;
1938+ let invoice =
1939+ client_node. bolt11_payment ( ) . receive ( amount_msat, & invoice_description, 1024 ) . unwrap ( ) ;
1940+
1941+ // Have the payer_node pay the invoice, to check regular forwards service_node -> client_node
1942+ // are working as expected.
1943+ println ! ( "Paying regular invoice!" ) ;
1944+ let payment_id = payer_node. bolt11_payment ( ) . send ( & invoice, None ) . unwrap ( ) ;
1945+ expect_payment_successful_event ! ( payer_node, Some ( payment_id) , None ) ;
1946+ expect_event ! ( service_node, PaymentForwarded ) ;
1947+ expect_payment_received_event ! ( client_node, amount_msat) ;
1948+
1949+ // Abort the spawned tasks at the end of the test
1950+ service_handle. abort ( ) ;
1951+ client_handle. abort ( ) ;
1952+ }
1953+
18021954#[ test]
18031955fn facade_logging ( ) {
18041956 let ( _bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
0 commit comments