@@ -790,7 +790,7 @@ pub async fn splice_in_with_all(
790790
791791pub ( crate ) async fn do_channel_full_cycle < E : ElectrumApi > (
792792 node_a : TestNode , node_b : TestNode , bitcoind : & BitcoindClient , electrsd : & E , allow_0conf : bool ,
793- expect_anchor_channel : bool , force_close : bool ,
793+ allow_0reserve : bool , expect_anchor_channel : bool , force_close : bool ,
794794) {
795795 let addr_a = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
796796 let addr_b = node_b. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
@@ -846,15 +846,27 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
846846 println ! ( "\n A -- open_channel -> B" ) ;
847847 let funding_amount_sat = 2_080_000 ;
848848 let push_msat = ( funding_amount_sat / 2 ) * 1000 ; // balance the channel
849- node_a
850- . open_announced_channel (
851- node_b. node_id ( ) ,
852- node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
853- funding_amount_sat,
854- Some ( push_msat) ,
855- None ,
856- )
857- . unwrap ( ) ;
849+ if allow_0reserve {
850+ node_a
851+ . open_0reserve_channel (
852+ node_b. node_id ( ) ,
853+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
854+ funding_amount_sat,
855+ Some ( push_msat) ,
856+ None ,
857+ )
858+ . unwrap ( ) ;
859+ } else {
860+ node_a
861+ . open_announced_channel (
862+ node_b. node_id ( ) ,
863+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
864+ funding_amount_sat,
865+ Some ( push_msat) ,
866+ None ,
867+ )
868+ . unwrap ( ) ;
869+ }
858870
859871 assert_eq ! ( node_a. list_peers( ) . first( ) . unwrap( ) . node_id, node_b. node_id( ) ) ;
860872 assert ! ( node_a. list_peers( ) . first( ) . unwrap( ) . is_persisted) ;
@@ -913,6 +925,22 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
913925 node_b_anchor_reserve_sat
914926 ) ;
915927
928+ // Note that only node B has 0-reserve, we don't yet have an API to allow the opener of the
929+ // channel to have 0-reserve.
930+ if allow_0reserve {
931+ assert_eq ! ( node_b. list_channels( ) [ 0 ] . unspendable_punishment_reserve, Some ( 0 ) ) ;
932+ assert_eq ! ( node_b. list_channels( ) [ 0 ] . outbound_capacity_msat, push_msat) ;
933+ assert_eq ! ( node_b. list_channels( ) [ 0 ] . next_outbound_htlc_limit_msat, push_msat) ;
934+
935+ assert_eq ! ( node_b. list_balances( ) . total_lightning_balance_sats * 1000 , push_msat) ;
936+ let LightningBalance :: ClaimableOnChannelClose { amount_satoshis, .. } =
937+ node_b. list_balances ( ) . lightning_balances [ 0 ]
938+ else {
939+ panic ! ( "Unexpected `LightningBalance` variant" ) ;
940+ } ;
941+ assert_eq ! ( amount_satoshis * 1000 , push_msat) ;
942+ }
943+
916944 let user_channel_id_a = expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
917945 let user_channel_id_b = expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
918946
@@ -1267,6 +1295,37 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
12671295 2
12681296 ) ;
12691297
1298+ if allow_0reserve {
1299+ let node_a_outbound_capacity_msat = node_a. list_channels ( ) [ 0 ] . outbound_capacity_msat ;
1300+ let node_a_reserve_msat =
1301+ node_a. list_channels ( ) [ 0 ] . unspendable_punishment_reserve . unwrap ( ) * 1000 ;
1302+ // TODO: Update this for zero-fee commitment channels
1303+ let node_a_anchors_msat = if expect_anchor_channel { 2 * 330 * 1000 } else { 0 } ;
1304+ let funding_amount_msat = node_a. list_channels ( ) [ 0 ] . channel_value_sats * 1000 ;
1305+ // Node B does not have any reserve, so we only subtract a few items on node A's
1306+ // side to arrive at node B's capacity
1307+ let node_b_capacity_msat = funding_amount_msat
1308+ - node_a_outbound_capacity_msat
1309+ - node_a_reserve_msat
1310+ - node_a_anchors_msat;
1311+ let got_capacity_msat = node_b. list_channels ( ) [ 0 ] . outbound_capacity_msat ;
1312+ assert_eq ! ( got_capacity_msat, node_b_capacity_msat) ;
1313+ assert_ne ! ( got_capacity_msat, 0 ) ;
1314+ // Sanity check to make sure this is a non-trivial amount
1315+ assert ! ( got_capacity_msat > 15_000_000 ) ;
1316+
1317+ // This is a private channel, so node B can send 100% of the value over
1318+ assert_eq ! ( node_b. list_channels( ) [ 0 ] . next_outbound_htlc_limit_msat, node_b_capacity_msat) ;
1319+
1320+ node_b. spontaneous_payment ( ) . send ( node_b_capacity_msat, node_a. node_id ( ) , None ) . unwrap ( ) ;
1321+ expect_event ! ( node_b, PaymentSuccessful ) ;
1322+ expect_event ! ( node_a, PaymentReceived ) ;
1323+
1324+ node_a. spontaneous_payment ( ) . send ( node_b_capacity_msat, node_b. node_id ( ) , None ) . unwrap ( ) ;
1325+ expect_event ! ( node_a, PaymentSuccessful ) ;
1326+ expect_event ! ( node_b, PaymentReceived ) ;
1327+ }
1328+
12701329 println ! ( "\n B close_channel (force: {})" , force_close) ;
12711330 tokio:: time:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
12721331 if force_close {
0 commit comments