Skip to content

Commit 82469e4

Browse files
committed
Support negotiating anchors throughout channel open
1 parent 2ce4d90 commit 82469e4

File tree

4 files changed

+251
-22
lines changed

4 files changed

+251
-22
lines changed

lightning/src/ln/channel.rs

Lines changed: 213 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -881,11 +881,20 @@ impl<Signer: Sign> Channel<Signer> {
881881
// The default channel type (ie the first one we try) depends on whether the channel is
882882
// public - if it is, we just go with `only_static_remotekey` as it's the only option
883883
// available. If it's private, we first try `scid_privacy` as it provides better privacy
884-
// with no other changes, and fall back to `only_static_remotekey`
884+
// with no other changes, and fall back to `only_static_remotekey`.
885885
let mut ret = ChannelTypeFeatures::only_static_remote_key();
886886
if !config.channel_handshake_config.announced_channel && config.channel_handshake_config.negotiate_scid_privacy {
887887
ret.set_scid_privacy_required();
888888
}
889+
890+
// Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
891+
// set it now. If they don't understand it, we'll fall back to our default of
892+
// `only_static_remotekey`.
893+
#[cfg(anchors)]
894+
if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx {
895+
ret.set_anchors_zero_fee_htlc_tx_required();
896+
}
897+
889898
ret
890899
}
891900

@@ -898,7 +907,16 @@ impl<Signer: Sign> Channel<Signer> {
898907
// We've exhausted our options
899908
return Err(());
900909
}
901-
self.channel_type = ChannelTypeFeatures::only_static_remote_key(); // We only currently support two types
910+
// We support opening a few different types of channels. Try removing our additional
911+
// features one by one until we've either arrived at our default or the counterparty has
912+
// accepted one.
913+
if self.channel_type.supports_anchors_zero_fee_htlc_tx() {
914+
self.channel_type.clear_anchors_zero_fee_htlc_tx();
915+
} else if self.channel_type.supports_scid_privacy() {
916+
self.channel_type.clear_scid_privacy();
917+
} else {
918+
self.channel_type = ChannelTypeFeatures::only_static_remote_key();
919+
}
902920
Ok(self.get_open_channel(chain_hash))
903921
}
904922

@@ -911,7 +929,11 @@ impl<Signer: Sign> Channel<Signer> {
911929
where K::Target: KeysInterface<Signer = Signer>,
912930
F::Target: FeeEstimator,
913931
{
914-
let opt_anchors = false; // TODO - should be based on features
932+
#[cfg(anchors)]
933+
let opt_anchors = config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
934+
their_features.supports_anchors_zero_fee_htlc_tx();
935+
#[cfg(not(anchors))]
936+
let opt_anchors = false;
915937

916938
let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay;
917939
let channel_keys_id = keys_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
@@ -1124,7 +1146,6 @@ impl<Signer: Sign> Channel<Signer> {
11241146
F::Target: FeeEstimator,
11251147
L::Target: Logger,
11261148
{
1127-
let opt_anchors = false; // TODO - should be based on features
11281149
let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
11291150

11301151
// First check the channel type is known, failing before we do anything else if we don't
@@ -1138,13 +1159,24 @@ impl<Signer: Sign> Channel<Signer> {
11381159
return Err(ChannelError::Close("Channel Type field contains unknown bits".to_owned()));
11391160
}
11401161

1141-
// We currently only allow four channel types, so write it all out here - we allow
1142-
// `only_static_remote_key` or `static_remote_key | zero_conf` in all contexts, and
1143-
// further allow `static_remote_key | scid_privacy` or
1144-
// `static_remote_key | scid_privacy | zero_conf`, if the channel is not
1145-
// publicly announced.
1162+
// We currently allow 8 channel types, and all must support `static_remote_key`, so
1163+
// write it all out here - we allow
1164+
// - `only_static_remote_key`
1165+
// - `static_remote_key | zero_conf`
1166+
// - `static_remote_key | scid_privacy`
1167+
// - `static_remote_key | scid_privacy | zero_conf`
1168+
// - `static_remote_key | anchors_zero_fee_htlc_tx`
1169+
// - `static_remote_key | anchors_zero_fee_htlc_tx | zero_conf`
1170+
// - `static_remote_key | anchors_zero_fee_htlc_tx | scid_privacy`
1171+
// - `static_remote_key | anchors_zero_fee_htlc_tx | scid_privacy | zero_conf`
1172+
if !channel_type.requires_static_remote_key() {
1173+
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
1174+
}
11461175
if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
1147-
if !channel_type.requires_scid_privacy() && !channel_type.requires_zero_conf() {
1176+
// If we have more features than just `static_remote_key`, make sure we only allow
1177+
// those we support.
1178+
if !channel_type.requires_scid_privacy() && !channel_type.requires_zero_conf() &&
1179+
!channel_type.requires_anchors_zero_fee_htlc_tx() {
11481180
return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
11491181
}
11501182

@@ -1154,11 +1186,16 @@ impl<Signer: Sign> Channel<Signer> {
11541186
}
11551187
channel_type.clone()
11561188
} else {
1157-
ChannelTypeFeatures::from_counterparty_init(&their_features)
1189+
let channel_type = ChannelTypeFeatures::from_counterparty_init(&their_features);
1190+
if channel_type.requires_unknown_bits() {
1191+
return Err(ChannelError::Close("Peer's features contain unknown ChannelType features".to_owned()));
1192+
}
1193+
channel_type
11581194
};
1159-
if !channel_type.supports_static_remote_key() {
1160-
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
1161-
}
1195+
#[cfg(anchors)]
1196+
let opt_anchors = channel_type.supports_anchors_zero_fee_htlc_tx();
1197+
#[cfg(not(anchors))]
1198+
let opt_anchors = false;
11621199

11631200
let channel_keys_id = keys_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id);
11641201
let holder_signer = keys_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id);
@@ -2128,7 +2165,16 @@ impl<Signer: Sign> Channel<Signer> {
21282165
} else if their_features.supports_channel_type() {
21292166
// Assume they've accepted the channel type as they said they understand it.
21302167
} else {
2131-
self.channel_type = ChannelTypeFeatures::from_counterparty_init(&their_features)
2168+
let channel_type = ChannelTypeFeatures::from_counterparty_init(&their_features);
2169+
if channel_type.requires_unknown_bits() {
2170+
return Err(ChannelError::Close("Peer's features contain unknown ChannelType features".to_owned()));
2171+
}
2172+
self.channel_type = channel_type;
2173+
self.channel_transaction_parameters.opt_anchors = if self.channel_type.supports_anchors_zero_fee_htlc_tx() {
2174+
Some(())
2175+
} else {
2176+
None
2177+
};
21322178
}
21332179

21342180
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
@@ -6654,11 +6700,6 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
66546700
return Err(DecodeError::UnknownRequiredFeature);
66556701
}
66566702

6657-
if channel_parameters.opt_anchors.is_some() {
6658-
// Relax this check when ChannelTypeFeatures supports anchors.
6659-
return Err(DecodeError::InvalidValue);
6660-
}
6661-
66626703
let mut secp_ctx = Secp256k1::new();
66636704
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
66646705

@@ -6793,6 +6834,8 @@ mod tests {
67936834
use hex;
67946835
use crate::ln::PaymentHash;
67956836
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
6837+
#[cfg(anchors)]
6838+
use crate::ln::channel::InitFeatures;
67966839
use crate::ln::channel::{Channel, InboundHTLCOutput, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator};
67976840
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
67986841
use crate::ln::features::ChannelTypeFeatures;
@@ -6807,6 +6850,8 @@ mod tests {
68076850
use crate::util::config::UserConfig;
68086851
use crate::util::enforcing_trait_impls::EnforcingSigner;
68096852
use crate::util::errors::APIError;
6853+
#[cfg(anchors)]
6854+
use crate::util::ser::Writeable;
68106855
use crate::util::test_utils;
68116856
use crate::util::test_utils::OnGetShutdownScriptpubkey;
68126857
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Scalar};
@@ -8069,4 +8114,152 @@ mod tests {
80698114
node_b_node_id, &channelmanager::provided_init_features(), &open_channel_msg, 7, &config, 0, &&logger, 42);
80708115
assert!(res.is_ok());
80718116
}
8117+
8118+
#[cfg(anchors)]
8119+
#[test]
8120+
fn test_supports_anchors_zero_htlc_tx_fee() {
8121+
// Tests that if both sides support and negotiate `anchors_zero_fee_htlc_tx`, it is the
8122+
// resulting `channel_type`.
8123+
let secp_ctx = Secp256k1::new();
8124+
let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
8125+
let network = Network::Testnet;
8126+
let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
8127+
let logger = test_utils::TestLogger::new();
8128+
8129+
let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
8130+
let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
8131+
8132+
let mut config = UserConfig::default();
8133+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
8134+
8135+
let mut expected_channel_type = ChannelTypeFeatures::empty();
8136+
expected_channel_type.set_static_remote_key_required();
8137+
expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
8138+
8139+
let channel_a = Channel::<EnforcingSigner>::new_outbound(
8140+
&fee_estimator, &&keys_provider, node_id_b, &channelmanager::provided_init_features(),
8141+
10000000, 100000, 42, &config, 0, 42
8142+
).unwrap();
8143+
8144+
let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
8145+
let channel_b = Channel::<EnforcingSigner>::new_from_req(
8146+
&fee_estimator, &&keys_provider, node_id_a, &channelmanager::provided_init_features(),
8147+
&open_channel_msg, 7, &config, 0, &&logger, 42
8148+
).unwrap();
8149+
8150+
assert_eq!(channel_a.channel_type, expected_channel_type);
8151+
assert_eq!(channel_b.channel_type, expected_channel_type);
8152+
}
8153+
8154+
#[cfg(anchors)]
8155+
#[test]
8156+
fn test_rejects_implicit_simple_anchors() {
8157+
// Tests that if `option_anchors` is being negotiated implicitly through the intersection of
8158+
// each side's `InitFeatures`, it is rejected.
8159+
let secp_ctx = Secp256k1::new();
8160+
let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
8161+
let network = Network::Testnet;
8162+
let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
8163+
let logger = test_utils::TestLogger::new();
8164+
8165+
let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
8166+
let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
8167+
8168+
let config = UserConfig::default();
8169+
8170+
// See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md
8171+
let static_remote_key_required: u64 = 1 << 12;
8172+
let simple_anchors_required: u64 = 1 << 20;
8173+
let raw_init_features = static_remote_key_required | simple_anchors_required;
8174+
let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
8175+
8176+
let channel_a = Channel::<EnforcingSigner>::new_outbound(
8177+
&fee_estimator, &&keys_provider, node_id_b, &channelmanager::provided_init_features(),
8178+
10000000, 100000, 42, &config, 0, 42
8179+
).unwrap();
8180+
8181+
// Set `channel_type` to `None` to force the implicit feature negotiation.
8182+
let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
8183+
open_channel_msg.channel_type = None;
8184+
8185+
// Since A supports both `static_remote_key` and `option_anchors`, but B only supports
8186+
// `static_remote_key`, the resulting channel will succeed with only `static_remote_key`.
8187+
let channel_b = Channel::<EnforcingSigner>::new_from_req(
8188+
&fee_estimator, &&keys_provider, node_id_a, &init_features_with_simple_anchors,
8189+
&open_channel_msg, 7, &config, 0, &&logger, 42
8190+
).unwrap();
8191+
8192+
// Verify the resulting `channel_type` is indeed only `static_remote_key`.
8193+
let mut encoded_channel_type = [0; 8];
8194+
encoded_channel_type[1..8].copy_from_slice(channel_b.channel_type.encode().as_slice());
8195+
let mut encoded_only_static_remote_key = [0; 8];
8196+
encoded_only_static_remote_key[6..8].copy_from_slice(ChannelTypeFeatures::only_static_remote_key().encode().as_slice());
8197+
assert_eq!(u64::from_be_bytes(encoded_channel_type), u64::from_be_bytes(encoded_only_static_remote_key));
8198+
assert_eq!(u64::from_be_bytes(encoded_channel_type), u64::from_be_bytes(encoded_only_static_remote_key));
8199+
}
8200+
8201+
#[cfg(anchors)]
8202+
#[test]
8203+
fn test_rejects_simple_anchors_channel_type() {
8204+
// Tests that if `option_anchors` is being negotiated through the `channel_type` feature,
8205+
// it is rejected.
8206+
let secp_ctx = Secp256k1::new();
8207+
let fee_estimator = LowerBoundedFeeEstimator::new(&TestFeeEstimator{fee_est: 15000});
8208+
let network = Network::Testnet;
8209+
let keys_provider = test_utils::TestKeysInterface::new(&[42; 32], network);
8210+
let logger = test_utils::TestLogger::new();
8211+
8212+
let node_id_a = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
8213+
let node_id_b = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
8214+
8215+
let config = UserConfig::default();
8216+
8217+
// See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md
8218+
let static_remote_key_required: u64 = 1 << 12;
8219+
let simple_anchors_required: u64 = 1 << 20;
8220+
let simple_anchors_raw_features = static_remote_key_required | simple_anchors_required;
8221+
let simple_anchors_features = InitFeatures::from_le_bytes(simple_anchors_raw_features.to_le_bytes().to_vec());
8222+
let simple_anchors_channel_type = ChannelTypeFeatures::from_counterparty_init(&simple_anchors_features);
8223+
8224+
// First, we'll try to open a channel between A and B where A requests a channel type for
8225+
// the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
8226+
// B as it's not supported by LDK.
8227+
let channel_a = Channel::<EnforcingSigner>::new_outbound(
8228+
&fee_estimator, &&keys_provider, node_id_b, &channelmanager::provided_init_features(),
8229+
10000000, 100000, 42, &config, 0, 42
8230+
).unwrap();
8231+
8232+
let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
8233+
open_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
8234+
8235+
let res = Channel::<EnforcingSigner>::new_from_req(
8236+
&fee_estimator, &&keys_provider, node_id_a, &simple_anchors_features, &open_channel_msg,
8237+
7, &config, 0, &&logger, 42
8238+
);
8239+
assert!(res.is_err());
8240+
8241+
// Then, we'll try to open another channel where A requests a channel type for
8242+
// `anchors_zero_fee_htlc_tx`. B is malicious and tries to downgrade the channel type to the
8243+
// original `option_anchors` feature, which should be rejected by A as it's not supported by
8244+
// LDK.
8245+
let mut channel_a = Channel::<EnforcingSigner>::new_outbound(
8246+
&fee_estimator, &&keys_provider, node_id_b, &simple_anchors_features,
8247+
10000000, 100000, 42, &config, 0, 42
8248+
).unwrap();
8249+
8250+
let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
8251+
8252+
let channel_b = Channel::<EnforcingSigner>::new_from_req(
8253+
&fee_estimator, &&keys_provider, node_id_a, &channelmanager::provided_init_features(),
8254+
&open_channel_msg, 7, &config, 0, &&logger, 42
8255+
).unwrap();
8256+
8257+
let mut accept_channel_msg = channel_b.get_accept_channel_message();
8258+
accept_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
8259+
8260+
let res = channel_a.accept_channel(
8261+
&accept_channel_msg, &config.channel_handshake_limits, &simple_anchors_features
8262+
);
8263+
assert!(res.is_err());
8264+
}
80728265
}

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6559,6 +6559,7 @@ pub fn provided_init_features() -> InitFeatures {
65596559
features.set_channel_type_optional();
65606560
features.set_scid_privacy_optional();
65616561
features.set_zero_conf_optional();
6562+
#[cfg(anchors)]
65626563
features.set_anchors_zero_fee_htlc_tx_optional();
65636564
features
65646565
}

lightning/src/ln/features.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,18 @@ impl<T: sealed::Wumbo> Features<T> {
698698
}
699699
}
700700

701+
impl<T: sealed::SCIDPrivacy> Features<T> {
702+
pub(crate) fn clear_scid_privacy(&mut self) {
703+
<T as sealed::SCIDPrivacy>::clear_bits(&mut self.flags);
704+
}
705+
}
706+
707+
impl<T: sealed::AnchorsZeroFeeHtlcTx> Features<T> {
708+
pub(crate) fn clear_anchors_zero_fee_htlc_tx(&mut self) {
709+
<T as sealed::AnchorsZeroFeeHtlcTx>::clear_bits(&mut self.flags);
710+
}
711+
}
712+
701713
#[cfg(test)]
702714
impl<T: sealed::UnknownFeature> Features<T> {
703715
pub(crate) fn unknown() -> Self {
@@ -787,6 +799,7 @@ mod tests {
787799
init_features.set_channel_type_optional();
788800
init_features.set_scid_privacy_optional();
789801
init_features.set_zero_conf_optional();
802+
init_features.set_anchors_zero_fee_htlc_tx_optional();
790803

791804
assert!(init_features.initial_routing_sync());
792805
assert!(!init_features.supports_upfront_shutdown_script());

lightning/src/util/config.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ pub struct ChannelHandshakeConfig {
126126
///
127127
/// [`KeysInterface::get_shutdown_scriptpubkey`]: crate::chain::keysinterface::KeysInterface::get_shutdown_scriptpubkey
128128
pub commit_upfront_shutdown_pubkey: bool,
129-
130129
/// The Proportion of the channel value to configure as counterparty's channel reserve,
131130
/// i.e., `their_channel_reserve_satoshis` for both outbound and inbound channels.
132131
///
@@ -149,7 +148,28 @@ pub struct ChannelHandshakeConfig {
149148
/// as 1000 sats instead, which is a safe implementation-specific lower bound.
150149
/// Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
151150
/// instead, although channel negotiations will fail in that case.
152-
pub their_channel_reserve_proportional_millionths: u32
151+
pub their_channel_reserve_proportional_millionths: u32,
152+
#[cfg(anchors)]
153+
/// If set, we attempt to negotiate the `anchors_zero_fee_htlc_tx`option for outbound channels.
154+
///
155+
/// If this option is set, channels may be created that will not be readable by LDK versions
156+
/// prior to 0.0.114, causing [`ChannelManager`]'s read method to return a
157+
/// [`DecodeError::InvalidValue`].
158+
///
159+
/// Note that setting this to true does *not* prevent us from opening channels with
160+
/// counterparties that do not support the `anchors_zero_fee_htlc_tx` option; we will simply
161+
/// fall back to a `static_remote_key` channel.
162+
///
163+
/// LDK will not support the legacy `option_anchors` commitment version due to a discovered
164+
/// vulnerability after its deployment. For more context, see the [`SIGHASH_SINGLE + update_fee
165+
/// Considered Harmful`] mailing list post.
166+
///
167+
/// Default value: false. This value is likely to change to true in the future.
168+
///
169+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
170+
/// [`DecodeError::InvalidValue`]: crate::ln::msgs::DecodeError::InvalidValue
171+
/// [`SIGHASH_SINGLE + update_fee Considered Harmful`]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html
172+
pub negotiate_anchors_zero_fee_htlc_tx: bool,
153173
}
154174

155175
impl Default for ChannelHandshakeConfig {
@@ -163,6 +183,8 @@ impl Default for ChannelHandshakeConfig {
163183
announced_channel: false,
164184
commit_upfront_shutdown_pubkey: true,
165185
their_channel_reserve_proportional_millionths: 10_000,
186+
#[cfg(anchors)]
187+
negotiate_anchors_zero_fee_htlc_tx: false,
166188
}
167189
}
168190
}

0 commit comments

Comments
 (0)