Skip to content

Commit 3ba79a9

Browse files
committed
ln/refactor: move channel acceptance tests to separate file
1 parent 52b4b6f commit 3ba79a9

File tree

2 files changed

+247
-0
lines changed

2 files changed

+247
-0
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#![cfg_attr(rustfmt, rustfmt_skip)]
2+
3+
use lightning_types::features::ChannelTypeFeatures;
4+
use crate::events::Event;
5+
use crate::util::config::{ChannelConfigOverrides, UserConfig, ChannelHandshakeConfigUpdate};
6+
use crate::ln::functional_test_utils::*;
7+
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, AcceptChannel, ErrorAction, MessageSendEvent};
8+
9+
#[test]
10+
fn test_inbound_anchors_manual_acceptance() {
11+
let mut anchors_cfg = test_default_channel_config();
12+
anchors_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
13+
do_test_manual_inbound_accept_with_override(anchors_cfg, None);
14+
}
15+
16+
#[test]
17+
fn test_inbound_anchors_manual_acceptance_overridden() {
18+
let overrides = ChannelConfigOverrides {
19+
handshake_overrides: Some(ChannelHandshakeConfigUpdate {
20+
max_inbound_htlc_value_in_flight_percent_of_channel: Some(5),
21+
htlc_minimum_msat: Some(1000),
22+
minimum_depth: Some(2),
23+
to_self_delay: Some(200),
24+
max_accepted_htlcs: Some(5),
25+
channel_reserve_proportional_millionths: Some(20000),
26+
}),
27+
update_overrides: None,
28+
};
29+
30+
let mut anchors_cfg = test_default_channel_config();
31+
anchors_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
32+
33+
let accept_message = do_test_manual_inbound_accept_with_override(anchors_cfg, Some(overrides));
34+
assert_eq!(accept_message.common_fields.max_htlc_value_in_flight_msat, 5_000_000);
35+
assert_eq!(accept_message.common_fields.htlc_minimum_msat, 1_000);
36+
assert_eq!(accept_message.common_fields.minimum_depth, 2);
37+
assert_eq!(accept_message.common_fields.to_self_delay, 200);
38+
assert_eq!(accept_message.common_fields.max_accepted_htlcs, 5);
39+
assert_eq!(accept_message.channel_reserve_satoshis, 2_000);
40+
}
41+
42+
#[test]
43+
fn test_inbound_zero_fee_commitments_manual_acceptance() {
44+
let mut zero_fee_cfg = test_default_channel_config();
45+
zero_fee_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
46+
do_test_manual_inbound_accept_with_override(zero_fee_cfg, None);
47+
}
48+
49+
fn do_test_manual_inbound_accept_with_override(start_cfg: UserConfig,
50+
config_overrides: Option<ChannelConfigOverrides>) -> AcceptChannel {
51+
52+
let mut mannual_accept_cfg = start_cfg.clone();
53+
mannual_accept_cfg.manually_accept_inbound_channels = true;
54+
55+
let chanmon_cfgs = create_chanmon_cfgs(3);
56+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
57+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs,
58+
&[Some(start_cfg.clone()), Some(start_cfg.clone()), Some(mannual_accept_cfg.clone())]);
59+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
60+
61+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
62+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
63+
64+
nodes[1].node.handle_open_channel(nodes[0].node.get_our_node_id(), &open_channel_msg);
65+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
66+
let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
67+
match &msg_events[0] {
68+
MessageSendEvent::HandleError { node_id, action } => {
69+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
70+
match action {
71+
ErrorAction::SendErrorMessage { msg } =>
72+
assert_eq!(msg.data, "No channels with anchor outputs accepted".to_owned()),
73+
_ => panic!("Unexpected error action"),
74+
}
75+
}
76+
_ => panic!("Unexpected event"),
77+
}
78+
79+
nodes[2].node.handle_open_channel(nodes[0].node.get_our_node_id(), &open_channel_msg);
80+
let events = nodes[2].node.get_and_clear_pending_events();
81+
match events[0] {
82+
Event::OpenChannelRequest { temporary_channel_id, .. } =>
83+
nodes[2].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 23, config_overrides).unwrap(),
84+
_ => panic!("Unexpected event"),
85+
}
86+
get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())
87+
}
88+
89+
#[test]
90+
fn test_anchors_zero_fee_htlc_tx_downgrade() {
91+
// Tests that if both nodes support anchors, but the remote node does not want to accept
92+
// anchor channels at the moment, an error it sent to the local node such that it can retry
93+
// the channel without the anchors feature.
94+
let mut initiator_cfg = test_default_channel_config();
95+
initiator_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
96+
97+
let mut receiver_cfg = test_default_channel_config();
98+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
99+
receiver_cfg.manually_accept_inbound_channels = true;
100+
101+
let start_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
102+
let end_type = ChannelTypeFeatures::only_static_remote_key();
103+
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, vec![end_type]);
104+
}
105+
106+
#[test]
107+
fn test_scid_privacy_downgrade() {
108+
// Tests downgrade from `anchors_zero_fee_commitments` with `option_scid_alias` when the
109+
// remote node advertises the features but does not accept the channel, asserting that
110+
// `option_scid_alias` is the last feature to be downgraded.
111+
let mut initiator_cfg = test_default_channel_config();
112+
initiator_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
113+
initiator_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
114+
initiator_cfg.channel_handshake_config.negotiate_scid_privacy = true;
115+
initiator_cfg.channel_handshake_config.announce_for_forwarding = false;
116+
117+
let mut receiver_cfg = test_default_channel_config();
118+
receiver_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
119+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
120+
receiver_cfg.channel_handshake_config.negotiate_scid_privacy = true;
121+
receiver_cfg.manually_accept_inbound_channels = true;
122+
123+
let mut start_type = ChannelTypeFeatures::anchors_zero_fee_commitments();
124+
start_type.set_scid_privacy_required();
125+
let mut with_anchors = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
126+
with_anchors.set_scid_privacy_required();
127+
let mut with_scid_privacy = ChannelTypeFeatures::only_static_remote_key();
128+
with_scid_privacy.set_scid_privacy_required();
129+
let static_remote = ChannelTypeFeatures::only_static_remote_key();
130+
let downgrade_types = vec![with_anchors, with_scid_privacy, static_remote];
131+
132+
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, downgrade_types);
133+
}
134+
135+
#[test]
136+
fn test_zero_fee_commitments_downgrade() {
137+
// Tests that the local node will retry without zero fee commitments in the case where the
138+
// remote node supports the feature but does not accept it.
139+
let mut initiator_cfg = test_default_channel_config();
140+
initiator_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
141+
initiator_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
142+
143+
let mut receiver_cfg = test_default_channel_config();
144+
receiver_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
145+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
146+
receiver_cfg.manually_accept_inbound_channels = true;
147+
148+
let start_type = ChannelTypeFeatures::anchors_zero_fee_commitments();
149+
let downgrade_types = vec![
150+
ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(),
151+
ChannelTypeFeatures::only_static_remote_key(),
152+
];
153+
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, downgrade_types);
154+
}
155+
156+
#[test]
157+
fn test_zero_fee_commitments_downgrade_to_static_remote() {
158+
// Tests that the local node will retry with static remote key when zero fee commitments
159+
// are supported (but not accepted), but not legacy anchors.
160+
let mut initiator_cfg = test_default_channel_config();
161+
initiator_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
162+
initiator_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
163+
164+
let mut receiver_cfg = test_default_channel_config();
165+
receiver_cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
166+
receiver_cfg.manually_accept_inbound_channels = true;
167+
168+
let start_type = ChannelTypeFeatures::anchors_zero_fee_commitments();
169+
let end_type = ChannelTypeFeatures::only_static_remote_key();
170+
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, vec![end_type]);
171+
}
172+
173+
fn do_test_channel_type_downgrade(initiator_cfg: UserConfig, acceptor_cfg: UserConfig,
174+
start_type: ChannelTypeFeatures, downgrade_types: Vec<ChannelTypeFeatures>) {
175+
let chanmon_cfgs = create_chanmon_cfgs(2);
176+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
177+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(initiator_cfg), Some(acceptor_cfg)]);
178+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
179+
let error_message = "Channel force-closed";
180+
181+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None, None).unwrap();
182+
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
183+
assert_eq!(open_channel_msg.common_fields.channel_type.as_ref().unwrap(), &start_type);
184+
185+
for downgrade_type in downgrade_types {
186+
nodes[1].node.handle_open_channel(nodes[0].node.get_our_node_id(), &open_channel_msg);
187+
let events = nodes[1].node.get_and_clear_pending_events();
188+
match events[0] {
189+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
190+
nodes[1].node.force_close_broadcasting_latest_txn(&temporary_channel_id, &nodes[0].node.get_our_node_id(), error_message.to_string()).unwrap();
191+
}
192+
_ => panic!("Unexpected event"),
193+
}
194+
195+
let error_msg = get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id());
196+
nodes[0].node.handle_error(nodes[1].node.get_our_node_id(), &error_msg);
197+
198+
open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
199+
let channel_type = open_channel_msg.common_fields.channel_type.as_ref().unwrap();
200+
assert_eq!(channel_type, &downgrade_type);
201+
202+
// Since nodes[1] should not have accepted the channel, it should
203+
// not have generated any events.
204+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
205+
}
206+
}
207+
208+
#[test]
209+
fn test_no_channel_downgrade() {
210+
// Tests that the local node will not retry when a `option_static_remote` channel is
211+
// rejected by a peer that advertises support for the feature.
212+
let initiator_cfg = test_default_channel_config();
213+
let mut receiver_cfg = test_default_channel_config();
214+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
215+
receiver_cfg.manually_accept_inbound_channels = true;
216+
217+
let chanmon_cfgs = create_chanmon_cfgs(2);
218+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
219+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(initiator_cfg), Some(receiver_cfg)]);
220+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
221+
let error_message = "Channel force-closed";
222+
223+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None, None).unwrap();
224+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
225+
let start_type = ChannelTypeFeatures::only_static_remote_key();
226+
assert_eq!(open_channel_msg.common_fields.channel_type.as_ref().unwrap(), &start_type);
227+
228+
nodes[1].node.handle_open_channel(nodes[0].node.get_our_node_id(), &open_channel_msg);
229+
let events = nodes[1].node.get_and_clear_pending_events();
230+
match events[0] {
231+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
232+
nodes[1].node.force_close_broadcasting_latest_txn(&temporary_channel_id, &nodes[0].node.get_our_node_id(), error_message.to_string()).unwrap();
233+
}
234+
_ => panic!("Unexpected event"),
235+
}
236+
237+
let error_msg = get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id());
238+
nodes[0].node.handle_error(nodes[1].node.get_our_node_id(), &error_msg);
239+
240+
// Since nodes[0] could not retry the channel with a different type, it should close it.
241+
let chan_closed_events = nodes[0].node.get_and_clear_pending_events();
242+
assert_eq!(chan_closed_events.len(), 1);
243+
if let Event::ChannelClosed { .. } = chan_closed_events[0] { } else { panic!(); }
244+
}

lightning/src/ln/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ pub mod bolt11_payment_tests;
7474
mod chanmon_update_fail_tests;
7575
#[cfg(test)]
7676
#[allow(unused_mut)]
77+
mod channel_acceptance_tests;
78+
#[cfg(test)]
79+
#[allow(unused_mut)]
7780
mod dual_funding_tests;
7881
#[cfg(any(test, feature = "_externalize_tests"))]
7982
#[allow(unused_mut)]

0 commit comments

Comments
 (0)