Skip to content

Commit a74d1f4

Browse files
committed
ln/refactor: use get_initial_channel_type for channel downgrade
Rather than duplicating our channel type preference ordering in downgrade logic, make a modified version of the remote peer's supported features and remove our current channel type from it to get the next preferred channel type.
1 parent a95b122 commit a74d1f4

File tree

2 files changed

+107
-19
lines changed

2 files changed

+107
-19
lines changed

lightning/src/ln/channel.rs

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ impl<SP: Deref> Channel<SP> where
15221522

15231523
pub fn maybe_handle_error_without_close<F: Deref, L: Deref>(
15241524
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
1525+
user_config: &UserConfig, their_features: &InitFeatures,
15251526
) -> Result<Option<OpenChannelMessage>, ()>
15261527
where
15271528
F::Target: FeeEstimator,
@@ -1532,13 +1533,17 @@ impl<SP: Deref> Channel<SP> where
15321533
ChannelPhase::Funded(_) => Ok(None),
15331534
ChannelPhase::UnfundedOutboundV1(chan) => {
15341535
let logger = WithChannelContext::from(logger, &chan.context, None);
1535-
chan.maybe_handle_error_without_close(chain_hash, fee_estimator, &&logger)
1536+
chan.maybe_handle_error_without_close(
1537+
chain_hash, fee_estimator, &&logger, user_config, their_features,
1538+
)
15361539
.map(|msg| Some(OpenChannelMessage::V1(msg)))
15371540
},
15381541
ChannelPhase::UnfundedInboundV1(_) => Ok(None),
15391542
ChannelPhase::UnfundedV2(chan) => {
15401543
if chan.funding.is_outbound() {
1541-
chan.maybe_handle_error_without_close(chain_hash, fee_estimator)
1544+
chan.maybe_handle_error_without_close(
1545+
chain_hash, fee_estimator, user_config, their_features,
1546+
)
15421547
.map(|msg| Some(OpenChannelMessage::V2(msg)))
15431548
} else {
15441549
Ok(None)
@@ -4833,7 +4838,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
48334838
/// of the channel type we tried, not of our ability to open any channel at all. We can see if a
48344839
/// downgrade of channel features would be possible so that we can still open the channel.
48354840
pub(crate) fn maybe_downgrade_channel_features<F: Deref>(
4836-
&mut self, funding: &mut FundingScope, fee_estimator: &LowerBoundedFeeEstimator<F>
4841+
&mut self, funding: &mut FundingScope, fee_estimator: &LowerBoundedFeeEstimator<F>,
4842+
user_config: &UserConfig, their_features: &InitFeatures,
48374843
) -> Result<(), ()>
48384844
where
48394845
F::Target: FeeEstimator
@@ -4854,21 +4860,33 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
48544860
// features one by one until we've either arrived at our default or the counterparty has
48554861
// accepted one.
48564862
//
4857-
// Due to the order below, we may not negotiate `option_anchors_zero_fee_htlc_tx` if the
4858-
// counterparty doesn't support `option_scid_privacy`. Since `get_initial_channel_type`
4859-
// checks whether the counterparty supports every feature, this would only happen if the
4860-
// counterparty is advertising the feature, but rejecting channels proposing the feature for
4861-
// whatever reason.
4862-
let channel_type = &mut funding.channel_transaction_parameters.channel_type_features;
4863+
// To downgrade the current channel type, we start with the remote party's full set of
4864+
// feature bits and un-set any features that are set for the current channel type or any
4865+
// channel types that come before it in our order of preference. This will allow us to
4866+
// negotiate the "next best" channel type per our ranking in `get_initial_channel_type`.
4867+
let channel_type = &funding.channel_transaction_parameters.channel_type_features;
4868+
let mut eligible_features = their_features.clone();
4869+
48634870
if channel_type.supports_anchors_zero_fee_htlc_tx() {
4864-
channel_type.clear_anchors_zero_fee_htlc_tx();
4865-
self.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee);
4866-
assert!(!channel_type.supports_anchors_nonzero_fee_htlc_tx());
4871+
eligible_features.clear_anchors_zero_fee_htlc_tx();
4872+
assert!(!eligible_features.supports_anchors_nonzero_fee_htlc_tx());
48674873
} else if channel_type.supports_scid_privacy() {
4868-
channel_type.clear_scid_privacy();
4869-
} else {
4870-
*channel_type = ChannelTypeFeatures::only_static_remote_key();
4874+
eligible_features.clear_scid_privacy();
4875+
eligible_features.clear_anchors_zero_fee_htlc_tx();
4876+
assert!(!eligible_features.supports_scid_privacy());
4877+
assert!(!eligible_features.supports_anchors_nonzero_fee_htlc_tx());
48714878
}
4879+
4880+
let next_channel_type = get_initial_channel_type(user_config, &eligible_features);
4881+
4882+
let conf_target = if next_channel_type.supports_anchors_zero_fee_htlc_tx() {
4883+
ConfirmationTarget::AnchorChannelFee
4884+
} else {
4885+
ConfirmationTarget::NonAnchorChannelFee
4886+
};
4887+
self.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(conf_target);
4888+
funding.channel_transaction_parameters.channel_type_features = next_channel_type;
4889+
48724890
Ok(())
48734891
}
48744892

@@ -9720,13 +9738,16 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
97209738
/// not of our ability to open any channel at all. Thus, on error, we should first call this
97219739
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
97229740
pub(crate) fn maybe_handle_error_without_close<F: Deref, L: Deref>(
9723-
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
9741+
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
9742+
user_config: &UserConfig, their_features: &InitFeatures,
97249743
) -> Result<msgs::OpenChannel, ()>
97259744
where
97269745
F::Target: FeeEstimator,
97279746
L::Target: Logger,
97289747
{
9729-
self.context.maybe_downgrade_channel_features(&mut self.funding, fee_estimator)?;
9748+
self.context.maybe_downgrade_channel_features(
9749+
&mut self.funding, fee_estimator, user_config, their_features,
9750+
)?;
97309751
self.get_open_channel(chain_hash, logger).ok_or(())
97319752
}
97329753

@@ -10234,12 +10255,15 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1023410255
/// not of our ability to open any channel at all. Thus, on error, we should first call this
1023510256
/// and see if we get a new `OpenChannelV2` message, otherwise the channel is failed.
1023610257
pub(crate) fn maybe_handle_error_without_close<F: Deref>(
10237-
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>
10258+
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>,
10259+
user_config: &UserConfig, their_features: &InitFeatures,
1023810260
) -> Result<msgs::OpenChannelV2, ()>
1023910261
where
1024010262
F::Target: FeeEstimator
1024110263
{
10242-
self.context.maybe_downgrade_channel_features(&mut self.funding, fee_estimator)?;
10264+
self.context.maybe_downgrade_channel_features(
10265+
&mut self.funding, fee_estimator, user_config, their_features,
10266+
)?;
1024310267
Ok(self.get_open_channel_v2(chain_hash))
1024410268
}
1024510269

lightning/src/ln/channelmanager.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12331,6 +12331,7 @@ where
1233112331
match peer_state.channel_by_id.get_mut(&msg.channel_id) {
1233212332
Some(chan) => match chan.maybe_handle_error_without_close(
1233312333
self.chain_hash, &self.fee_estimator, &self.logger,
12334+
&self.default_configuration, &peer_state.latest_features,
1233412335
) {
1233512336
Ok(Some(OpenChannelMessage::V1(msg))) => {
1233612337
peer_state.pending_msg_events.push(MessageSendEvent::SendOpenChannel {
@@ -16170,6 +16171,31 @@ mod tests {
1617016171
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, vec![end_type]);
1617116172
}
1617216173

16174+
#[test]
16175+
fn test_scid_privacy_downgrade() {
16176+
// Tests downgrade from `anchors_zero_fee_htlc_tx` with `option_scid_alias` when the
16177+
// remote node advertises the features but does not accept the channel, asserting that
16178+
// `option_scid_alias` is the last feature to be downgraded.
16179+
let mut initiator_cfg = test_default_channel_config();
16180+
initiator_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
16181+
initiator_cfg.channel_handshake_config.negotiate_scid_privacy = true;
16182+
initiator_cfg.channel_handshake_config.announce_for_forwarding = false;
16183+
16184+
let mut receiver_cfg = test_default_channel_config();
16185+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
16186+
receiver_cfg.channel_handshake_config.negotiate_scid_privacy = true;
16187+
receiver_cfg.manually_accept_inbound_channels = true;
16188+
16189+
let mut start_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
16190+
start_type.set_scid_privacy_required();
16191+
let mut with_scid_privacy = ChannelTypeFeatures::only_static_remote_key();
16192+
with_scid_privacy.set_scid_privacy_required();
16193+
let static_remote = ChannelTypeFeatures::only_static_remote_key();
16194+
let downgrade_types = vec![with_scid_privacy, static_remote];
16195+
16196+
do_test_channel_type_downgrade(initiator_cfg, receiver_cfg, start_type, downgrade_types);
16197+
}
16198+
1617316199
fn do_test_channel_type_downgrade(initiator_cfg: UserConfig, acceptor_cfg: UserConfig,
1617416200
start_type: ChannelTypeFeatures, downgrade_types: Vec<ChannelTypeFeatures>) {
1617516201
let chanmon_cfgs = create_chanmon_cfgs(2);
@@ -16205,6 +16231,44 @@ mod tests {
1620516231
}
1620616232
}
1620716233

16234+
#[test]
16235+
fn test_no_channel_downgrade() {
16236+
// Tests that the local node will not retry when a `option_static_remote` channel is
16237+
// rejected by a peer that advertises support for the feature.
16238+
let initiator_cfg = test_default_channel_config();
16239+
let mut receiver_cfg = test_default_channel_config();
16240+
receiver_cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
16241+
receiver_cfg.manually_accept_inbound_channels = true;
16242+
16243+
let chanmon_cfgs = create_chanmon_cfgs(2);
16244+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
16245+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(initiator_cfg), Some(receiver_cfg)]);
16246+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
16247+
let error_message = "Channel force-closed";
16248+
16249+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None, None).unwrap();
16250+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
16251+
let start_type = ChannelTypeFeatures::only_static_remote_key();
16252+
assert_eq!(open_channel_msg.common_fields.channel_type.as_ref().unwrap(), &start_type);
16253+
16254+
nodes[1].node.handle_open_channel(nodes[0].node.get_our_node_id(), &open_channel_msg);
16255+
let events = nodes[1].node.get_and_clear_pending_events();
16256+
match events[0] {
16257+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
16258+
nodes[1].node.force_close_broadcasting_latest_txn(&temporary_channel_id, &nodes[0].node.get_our_node_id(), error_message.to_string()).unwrap();
16259+
}
16260+
_ => panic!("Unexpected event"),
16261+
}
16262+
16263+
let error_msg = get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id());
16264+
nodes[0].node.handle_error(nodes[1].node.get_our_node_id(), &error_msg);
16265+
16266+
// Since nodes[0] could not retry the channel with a different type, it should close it.
16267+
let chan_closed_events = nodes[0].node.get_and_clear_pending_events();
16268+
assert_eq!(chan_closed_events.len(), 1);
16269+
if let Event::ChannelClosed { .. } = chan_closed_events[0] { } else { panic!(); }
16270+
}
16271+
1620816272
#[test]
1620916273
fn test_update_channel_config() {
1621016274
let chanmon_cfg = create_chanmon_cfgs(2);

0 commit comments

Comments
 (0)