Skip to content

Commit d327c23

Browse files
authored
Merge pull request #2368 from wpaulino/inbound-anchors-manual-acceptance
Require inbound channels with anchor outputs to be accepted manually
2 parents 6fd13d7 + e6348b8 commit d327c23

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

lightning/src/ln/channelmanager.rs

+50-2
Original file line numberDiff line numberDiff line change
@@ -5144,9 +5144,13 @@ where
51445144
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()))
51455145
} else {
51465146
if !self.default_configuration.manually_accept_inbound_channels {
5147-
if channel.context.get_channel_type().requires_zero_conf() {
5147+
let channel_type = channel.context.get_channel_type();
5148+
if channel_type.requires_zero_conf() {
51485149
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
51495150
}
5151+
if channel_type.requires_anchors_zero_fee_htlc_tx() {
5152+
return Err(MsgHandleErrInternal::send_err_msg_no_close("No channels with anchor outputs accepted".to_owned(), msg.temporary_channel_id.clone()));
5153+
}
51505154
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
51515155
node_id: counterparty_node_id.clone(),
51525156
msg: channel.accept_inbound_channel(user_channel_id),
@@ -8853,7 +8857,7 @@ mod tests {
88538857
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
88548858
use crate::ln::channelmanager::{inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId};
88558859
use crate::ln::functional_test_utils::*;
8856-
use crate::ln::msgs;
8860+
use crate::ln::msgs::{self, ErrorAction};
88578861
use crate::ln::msgs::ChannelMessageHandler;
88588862
use crate::routing::router::{PaymentParameters, RouteParameters, find_route};
88598863
use crate::util::errors::APIError;
@@ -9849,6 +9853,50 @@ mod tests {
98499853
sender_intended_amt_msat - extra_fee_msat, 42, None, true, Some(extra_fee_msat)).is_ok());
98509854
}
98519855

9856+
#[test]
9857+
fn test_inbound_anchors_manual_acceptance() {
9858+
// Tests that we properly limit inbound channels when we have the manual-channel-acceptance
9859+
// flag set and (sometimes) accept channels as 0conf.
9860+
let mut anchors_cfg = test_default_channel_config();
9861+
anchors_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
9862+
9863+
let mut anchors_manual_accept_cfg = anchors_cfg.clone();
9864+
anchors_manual_accept_cfg.manually_accept_inbound_channels = true;
9865+
9866+
let chanmon_cfgs = create_chanmon_cfgs(3);
9867+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
9868+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs,
9869+
&[Some(anchors_cfg.clone()), Some(anchors_cfg.clone()), Some(anchors_manual_accept_cfg.clone())]);
9870+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
9871+
9872+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
9873+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
9874+
9875+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
9876+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
9877+
let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
9878+
match &msg_events[0] {
9879+
MessageSendEvent::HandleError { node_id, action } => {
9880+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
9881+
match action {
9882+
ErrorAction::SendErrorMessage { msg } =>
9883+
assert_eq!(msg.data, "No channels with anchor outputs accepted".to_owned()),
9884+
_ => panic!("Unexpected error action"),
9885+
}
9886+
}
9887+
_ => panic!("Unexpected event"),
9888+
}
9889+
9890+
nodes[2].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
9891+
let events = nodes[2].node.get_and_clear_pending_events();
9892+
match events[0] {
9893+
Event::OpenChannelRequest { temporary_channel_id, .. } =>
9894+
nodes[2].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 23).unwrap(),
9895+
_ => panic!("Unexpected event"),
9896+
}
9897+
get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
9898+
}
9899+
98529900
#[test]
98539901
fn test_anchors_zero_fee_htlc_tx_fallback() {
98549902
// Tests that if both nodes support anchors, but the remote node does not want to accept

lightning/src/ln/functional_test_utils.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,15 @@ pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, '
11001100
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
11011101
assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42);
11021102
node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_channel_msg);
1103+
if node_b.node.get_current_default_configuration().manually_accept_inbound_channels {
1104+
let events = node_b.node.get_and_clear_pending_events();
1105+
assert_eq!(events.len(), 1);
1106+
match &events[0] {
1107+
Event::OpenChannelRequest { temporary_channel_id, counterparty_node_id, .. } =>
1108+
node_b.node.accept_inbound_channel(temporary_channel_id, counterparty_node_id, 42).unwrap(),
1109+
_ => panic!("Unexpected event"),
1110+
};
1111+
}
11031112
let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id());
11041113
assert_eq!(accept_channel_msg.temporary_channel_id, create_chan_id);
11051114
node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_channel_msg);

lightning/src/ln/monitor_tests.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,7 @@ fn do_test_monitor_rebroadcast_pending_claims(anchors: bool) {
17211721
let mut config = test_default_channel_config();
17221722
if anchors {
17231723
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
1724+
config.manually_accept_inbound_channels = true;
17241725
}
17251726
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), Some(config)]);
17261727
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -1870,6 +1871,7 @@ fn test_yield_anchors_events() {
18701871
let mut anchors_config = UserConfig::default();
18711872
anchors_config.channel_handshake_config.announced_channel = true;
18721873
anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
1874+
anchors_config.manually_accept_inbound_channels = true;
18731875
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config), Some(anchors_config)]);
18741876
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
18751877

@@ -2002,6 +2004,7 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
20022004
let mut anchors_config = UserConfig::default();
20032005
anchors_config.channel_handshake_config.announced_channel = true;
20042006
anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
2007+
anchors_config.manually_accept_inbound_channels = true;
20052008
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config), Some(anchors_config)]);
20062009

20072010
let bob_persister: test_utils::TestPersister;

lightning/src/util/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ pub struct ChannelHandshakeConfig {
153153
/// channels. This feature requires having a reserve of onchain funds readily available to bump
154154
/// transactions in the event of a channel force close to avoid the possibility of losing funds.
155155
///
156+
/// Note that if you wish accept inbound channels with anchor outputs, you must enable
157+
/// [`UserConfig::manually_accept_inbound_channels`] and manually accept them with
158+
/// [`ChannelManager::accept_inbound_channel`]. This is done to give you the chance to check
159+
/// whether your reserve of onchain funds is enough to cover the fees for all existing and new
160+
/// channels featuring anchor outputs in the event of a force close.
161+
///
156162
/// If this option is set, channels may be created that will not be readable by LDK versions
157163
/// prior to 0.0.116, causing [`ChannelManager`]'s read method to return a
158164
/// [`DecodeError::InvalidValue`].
@@ -168,6 +174,7 @@ pub struct ChannelHandshakeConfig {
168174
/// Default value: false. This value is likely to change to true in the future.
169175
///
170176
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
177+
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
171178
/// [`DecodeError::InvalidValue`]: crate::ln::msgs::DecodeError::InvalidValue
172179
/// [`SIGHASH_SINGLE + update_fee Considered Harmful`]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html
173180
pub negotiate_anchors_zero_fee_htlc_tx: bool,

0 commit comments

Comments
 (0)