Skip to content

Commit bca3cc4

Browse files
committed
Add tests for zero reserve channels
1 parent 64e3154 commit bca3cc4

File tree

3 files changed

+161
-20
lines changed

3 files changed

+161
-20
lines changed

tests/common/mod.rs

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ pub async fn splice_in_with_all(
790790

791791
pub(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!("\nA -- 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!("\nB close_channel (force: {})", force_close);
12711330
tokio::time::sleep(Duration::from_secs(1)).await;
12721331
if force_close {

tests/integration_tests_rust.rs

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,44 +48,125 @@ async fn channel_full_cycle() {
4848
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
4949
let chain_source = random_chain_source(&bitcoind, &electrsd);
5050
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false);
51-
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, false)
52-
.await;
51+
do_channel_full_cycle(
52+
node_a,
53+
node_b,
54+
&bitcoind.client,
55+
&electrsd.client,
56+
false,
57+
false,
58+
true,
59+
false,
60+
)
61+
.await;
5362
}
5463

5564
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
5665
async fn channel_full_cycle_force_close() {
5766
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
5867
let chain_source = random_chain_source(&bitcoind, &electrsd);
5968
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false);
60-
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, true)
61-
.await;
69+
do_channel_full_cycle(
70+
node_a,
71+
node_b,
72+
&bitcoind.client,
73+
&electrsd.client,
74+
false,
75+
false,
76+
true,
77+
true,
78+
)
79+
.await;
6280
}
6381

6482
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
6583
async fn channel_full_cycle_force_close_trusted_no_reserve() {
6684
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
6785
let chain_source = random_chain_source(&bitcoind, &electrsd);
6886
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, true);
69-
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, true)
70-
.await;
87+
do_channel_full_cycle(
88+
node_a,
89+
node_b,
90+
&bitcoind.client,
91+
&electrsd.client,
92+
false,
93+
false,
94+
true,
95+
true,
96+
)
97+
.await;
7198
}
7299

73100
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
74101
async fn channel_full_cycle_0conf() {
75102
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
76103
let chain_source = random_chain_source(&bitcoind, &electrsd);
77104
let (node_a, node_b) = setup_two_nodes(&chain_source, true, true, false);
78-
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, true, true, false)
79-
.await;
105+
do_channel_full_cycle(
106+
node_a,
107+
node_b,
108+
&bitcoind.client,
109+
&electrsd.client,
110+
true,
111+
false,
112+
true,
113+
false,
114+
)
115+
.await;
80116
}
81117

82118
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
83119
async fn channel_full_cycle_legacy_staticremotekey() {
84120
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
85121
let chain_source = random_chain_source(&bitcoind, &electrsd);
86122
let (node_a, node_b) = setup_two_nodes(&chain_source, false, false, false);
87-
do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, false, false)
88-
.await;
123+
do_channel_full_cycle(
124+
node_a,
125+
node_b,
126+
&bitcoind.client,
127+
&electrsd.client,
128+
false,
129+
false,
130+
false,
131+
false,
132+
)
133+
.await;
134+
}
135+
136+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
137+
async fn channel_full_cycle_0reserve() {
138+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
139+
let chain_source = random_chain_source(&bitcoind, &electrsd);
140+
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false);
141+
do_channel_full_cycle(
142+
node_a,
143+
node_b,
144+
&bitcoind.client,
145+
&electrsd.client,
146+
false,
147+
true,
148+
true,
149+
false,
150+
)
151+
.await;
152+
}
153+
154+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
155+
async fn channel_full_cycle_0conf_0reserve() {
156+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
157+
let chain_source = random_chain_source(&bitcoind, &electrsd);
158+
let (node_a, node_b) = setup_two_nodes(&chain_source, true, true, false);
159+
do_channel_full_cycle(
160+
node_a,
161+
node_b,
162+
&bitcoind.client,
163+
&electrsd.client,
164+
true,
165+
true,
166+
true,
167+
false,
168+
)
169+
.await;
89170
}
90171

91172
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]

tests/integration_tests_vss.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ async fn channel_full_cycle_with_vss_store() {
5454
&bitcoind.client,
5555
&electrsd.client,
5656
false,
57+
false,
5758
true,
5859
false,
5960
)

0 commit comments

Comments
 (0)