@@ -910,6 +910,147 @@ fn concurrent_connections_succeed() {
910910 }
911911}
912912
913+ #[ test]
914+ fn splice_channel ( ) {
915+ macro_rules! expect_splice_pending_event {
916+ ( $node: expr, $counterparty_node_id: expr) => { {
917+ match $node. wait_next_event( ) {
918+ ref e @ Event :: SplicePending { new_funding_txo, counterparty_node_id, .. } => {
919+ println!( "{} got event {:?}" , $node. node_id( ) , e) ;
920+ assert_eq!( counterparty_node_id, $counterparty_node_id) ;
921+ $node. event_handled( ) . unwrap( ) ;
922+ new_funding_txo
923+ } ,
924+ ref e => {
925+ panic!( "{} got unexpected event!: {:?}" , std:: stringify!( $node) , e) ;
926+ } ,
927+ }
928+ } } ;
929+ }
930+
931+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
932+ let chain_source = TestChainSource :: Esplora ( & electrsd) ;
933+ let ( node_a, node_b) = setup_two_nodes ( & chain_source, false , true , false ) ;
934+
935+ let address_a = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
936+ let address_b = node_b. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
937+ let premine_amount_sat = 5_000_000 ;
938+ premine_and_distribute_funds (
939+ & bitcoind. client ,
940+ & electrsd. client ,
941+ vec ! [ address_a, address_b] ,
942+ Amount :: from_sat ( premine_amount_sat) ,
943+ ) ;
944+
945+ node_a. sync_wallets ( ) . unwrap ( ) ;
946+ node_b. sync_wallets ( ) . unwrap ( ) ;
947+
948+ assert_eq ! ( node_a. list_balances( ) . total_onchain_balance_sats, premine_amount_sat) ;
949+ assert_eq ! ( node_b. list_balances( ) . total_onchain_balance_sats, premine_amount_sat) ;
950+
951+ open_channel ( & node_a, & node_b, 4_000_000 , false , & electrsd) ;
952+
953+ // Open a channel with Node A contributing the funding
954+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) ;
955+
956+ node_a. sync_wallets ( ) . unwrap ( ) ;
957+ node_b. sync_wallets ( ) . unwrap ( ) ;
958+
959+ let user_channel_id_a = expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
960+ let user_channel_id_b = expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
961+
962+ let opening_transaction_fee_sat = 156 ;
963+ let closing_transaction_fee_sat = 614 ;
964+ let anchor_output_sat = 330 ;
965+
966+ assert_eq ! (
967+ node_a. list_balances( ) . total_onchain_balance_sats,
968+ premine_amount_sat - 4_000_000 - opening_transaction_fee_sat
969+ ) ;
970+ assert_eq ! (
971+ node_a. list_balances( ) . total_lightning_balance_sats,
972+ 4_000_000 - closing_transaction_fee_sat - anchor_output_sat
973+ ) ;
974+ assert_eq ! ( node_b. list_balances( ) . total_lightning_balance_sats, 0 ) ;
975+
976+ // Test that splicing and payments fail when there are insufficient funds
977+ let address = node_b. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
978+ let amount_msat = 400_000_000 ;
979+
980+ assert_eq ! (
981+ node_b. splice_in( & user_channel_id_a, node_b. node_id( ) , 5_000_000 ) ,
982+ Err ( NodeError :: ChannelSplicingFailed ) ,
983+ ) ;
984+ assert_eq ! (
985+ node_b. splice_out( & user_channel_id_a, node_b. node_id( ) , address, amount_msat / 1000 ) ,
986+ Err ( NodeError :: ChannelSplicingFailed ) ,
987+ ) ;
988+ assert_eq ! (
989+ node_b. spontaneous_payment( ) . send( amount_msat, node_a. node_id( ) , None ) ,
990+ Err ( NodeError :: PaymentSendingFailed )
991+ ) ;
992+
993+ // Splice-in funds for Node B so that it has outbound liquidity to make a payment
994+ node_b. splice_in ( & user_channel_id_b, node_a. node_id ( ) , 4_000_000 ) . unwrap ( ) ;
995+
996+ expect_splice_pending_event ! ( node_a, node_b. node_id( ) ) ;
997+ expect_splice_pending_event ! ( node_b, node_a. node_id( ) ) ;
998+
999+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) ;
1000+
1001+ node_a. sync_wallets ( ) . unwrap ( ) ;
1002+ node_b. sync_wallets ( ) . unwrap ( ) ;
1003+
1004+ expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
1005+ expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
1006+
1007+ let splice_in_fee_sat = 253 ;
1008+
1009+ assert_eq ! (
1010+ node_b. list_balances( ) . total_onchain_balance_sats,
1011+ premine_amount_sat - 4_000_000 - splice_in_fee_sat
1012+ ) ;
1013+ assert_eq ! ( node_b. list_balances( ) . total_lightning_balance_sats, 4_000_000 ) ;
1014+
1015+ let payment_id =
1016+ node_b. spontaneous_payment ( ) . send ( amount_msat, node_a. node_id ( ) , None ) . unwrap ( ) ;
1017+
1018+ expect_payment_successful_event ! ( node_b, Some ( payment_id) , None ) ;
1019+ expect_payment_received_event ! ( node_a, amount_msat) ;
1020+
1021+ assert_eq ! (
1022+ node_a. list_balances( ) . total_lightning_balance_sats,
1023+ 4_000_000 - closing_transaction_fee_sat - anchor_output_sat + amount_msat / 1000
1024+ ) ;
1025+ assert_eq ! ( node_b. list_balances( ) . total_lightning_balance_sats, 4_000_000 - amount_msat / 1000 ) ;
1026+
1027+ // Splice-out funds for Node A from the payment sent by Node B
1028+ let address = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
1029+ node_a. splice_out ( & user_channel_id_a, node_b. node_id ( ) , address, amount_msat / 1000 ) . unwrap ( ) ;
1030+
1031+ expect_splice_pending_event ! ( node_a, node_b. node_id( ) ) ;
1032+ expect_splice_pending_event ! ( node_b, node_a. node_id( ) ) ;
1033+
1034+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) ;
1035+
1036+ node_a. sync_wallets ( ) . unwrap ( ) ;
1037+ node_b. sync_wallets ( ) . unwrap ( ) ;
1038+
1039+ expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
1040+ expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
1041+
1042+ let splice_out_fee_sat = 184 ;
1043+
1044+ assert_eq ! (
1045+ node_a. list_balances( ) . total_onchain_balance_sats,
1046+ premine_amount_sat - 4_000_000 - opening_transaction_fee_sat + amount_msat / 1000
1047+ ) ;
1048+ assert_eq ! (
1049+ node_a. list_balances( ) . total_lightning_balance_sats,
1050+ 4_000_000 - closing_transaction_fee_sat - anchor_output_sat - splice_out_fee_sat
1051+ ) ;
1052+ }
1053+
9131054#[ test]
9141055fn simple_bolt12_send_receive ( ) {
9151056 let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
0 commit comments