Skip to content

Commit c0bbd4d

Browse files
authored
Merge pull request #1078 from TheBlueMatt/2021-09-chan-types
Implement channel_type negotiation
2 parents e3bdfa0 + db2e7e7 commit c0bbd4d

File tree

4 files changed

+187
-29
lines changed

4 files changed

+187
-29
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl BackgroundProcessor {
155155
/// functionality implemented by other handlers.
156156
/// * [`NetGraphMsgHandler`] if given will update the [`NetworkGraph`] based on payment failures.
157157
///
158-
/// [top-level documentation]: Self
158+
/// [top-level documentation]: BackgroundProcessor
159159
/// [`join`]: Self::join
160160
/// [`stop`]: Self::stop
161161
/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager

lightning/src/ln/channel.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1,Signature};
2323
use bitcoin::secp256k1;
2424

2525
use ln::{PaymentPreimage, PaymentHash};
26-
use ln::features::{ChannelFeatures, InitFeatures};
26+
use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures};
2727
use ln::msgs;
2828
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
2929
use ln::script::{self, ShutdownScript};
@@ -550,6 +550,9 @@ pub(super) struct Channel<Signer: Sign> {
550550
// is fine, but as a sanity check in our failure to generate the second claim, we check here
551551
// that the original was a claim, and that we aren't now trying to fulfill a failed HTLC.
552552
historical_inbound_htlc_fulfills: HashSet<u64>,
553+
554+
/// This channel's type, as negotiated during channel open
555+
channel_type: ChannelTypeFeatures,
553556
}
554557

555558
#[cfg(any(test, feature = "fuzztarget"))]
@@ -775,6 +778,11 @@ impl<Signer: Sign> Channel<Signer> {
775778

776779
#[cfg(any(test, feature = "fuzztarget"))]
777780
historical_inbound_htlc_fulfills: HashSet::new(),
781+
782+
// We currently only actually support one channel type, so don't retry with new types
783+
// on error messages. When we support more we'll need fallback support (assuming we
784+
// want to support old types).
785+
channel_type: ChannelTypeFeatures::only_static_remote_key(),
778786
})
779787
}
780788

@@ -803,6 +811,23 @@ impl<Signer: Sign> Channel<Signer> {
803811
where K::Target: KeysInterface<Signer = Signer>,
804812
F::Target: FeeEstimator
805813
{
814+
// First check the channel type is known, failing before we do anything else if we don't
815+
// support this channel type.
816+
let channel_type = if let Some(channel_type) = &msg.channel_type {
817+
if channel_type.supports_any_optional_bits() {
818+
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
819+
}
820+
if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
821+
return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
822+
}
823+
channel_type.clone()
824+
} else {
825+
ChannelTypeFeatures::from_counterparty_init(&their_features)
826+
};
827+
if !channel_type.supports_static_remote_key() {
828+
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
829+
}
830+
806831
let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis);
807832
let pubkeys = holder_signer.pubkeys().clone();
808833
let counterparty_pubkeys = ChannelPublicKeys {
@@ -1043,6 +1068,8 @@ impl<Signer: Sign> Channel<Signer> {
10431068

10441069
#[cfg(any(test, feature = "fuzztarget"))]
10451070
historical_inbound_htlc_fulfills: HashSet::new(),
1071+
1072+
channel_type,
10461073
};
10471074

10481075
Ok(chan)
@@ -4283,6 +4310,7 @@ impl<Signer: Sign> Channel<Signer> {
42834310
Some(script) => script.clone().into_inner(),
42844311
None => Builder::new().into_script(),
42854312
}),
4313+
channel_type: Some(self.channel_type.clone()),
42864314
}
42874315
}
42884316

@@ -5240,6 +5268,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
52405268
(7, self.shutdown_scriptpubkey, option),
52415269
(9, self.target_closing_feerate_sats_per_kw, option),
52425270
(11, self.monitor_pending_finalized_fulfills, vec_type),
5271+
(13, self.channel_type, required),
52435272
});
52445273

52455274
Ok(())
@@ -5474,6 +5503,9 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
54745503
let mut announcement_sigs = None;
54755504
let mut target_closing_feerate_sats_per_kw = None;
54765505
let mut monitor_pending_finalized_fulfills = Some(Vec::new());
5506+
// Prior to supporting channel type negotiation, all of our channels were static_remotekey
5507+
// only, so we default to that if none was written.
5508+
let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
54775509
read_tlv_fields!(reader, {
54785510
(0, announcement_sigs, option),
54795511
(1, minimum_depth, option),
@@ -5482,8 +5514,16 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
54825514
(7, shutdown_scriptpubkey, option),
54835515
(9, target_closing_feerate_sats_per_kw, option),
54845516
(11, monitor_pending_finalized_fulfills, vec_type),
5517+
(13, channel_type, option),
54855518
});
54865519

5520+
let chan_features = channel_type.as_ref().unwrap();
5521+
if chan_features.supports_unknown_bits() || chan_features.requires_unknown_bits() {
5522+
// If the channel was written by a new version and negotiated with features we don't
5523+
// understand yet, refuse to read it.
5524+
return Err(DecodeError::UnknownRequiredFeature);
5525+
}
5526+
54875527
let mut secp_ctx = Secp256k1::new();
54885528
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
54895529

@@ -5576,6 +5616,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
55765616

55775617
#[cfg(any(test, feature = "fuzztarget"))]
55785618
historical_inbound_htlc_fulfills,
5619+
5620+
channel_type: channel_type.unwrap(),
55795621
})
55805622
}
55815623
}

lightning/src/ln/features.rs

Lines changed: 119 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
//! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
2323
//! [messages]: crate::ln::msgs
2424
25-
use io;
25+
use {io, io_extras};
2626
use prelude::*;
2727
use core::{cmp, fmt};
2828
use core::hash::{Hash, Hasher};
@@ -194,6 +194,30 @@ mod sealed {
194194
BasicMPP,
195195
],
196196
});
197+
// This isn't a "real" feature context, and is only used in the channel_type field in an
198+
// `OpenChannel` message.
199+
define_context!(ChannelTypeContext {
200+
required_features: [
201+
// Byte 0
202+
,
203+
// Byte 1
204+
StaticRemoteKey,
205+
// Byte 2
206+
,
207+
// Byte 3
208+
,
209+
],
210+
optional_features: [
211+
// Byte 0
212+
,
213+
// Byte 1
214+
,
215+
// Byte 2
216+
,
217+
// Byte 3
218+
,
219+
],
220+
});
197221

198222
/// Defines a feature with the given bits for the specified [`Context`]s. The generated trait is
199223
/// useful for manipulating feature flags.
@@ -325,7 +349,7 @@ mod sealed {
325349
define_feature!(9, VariableLengthOnion, [InitContext, NodeContext, InvoiceContext],
326350
"Feature flags for `var_onion_optin`.", set_variable_length_onion_optional,
327351
set_variable_length_onion_required);
328-
define_feature!(13, StaticRemoteKey, [InitContext, NodeContext],
352+
define_feature!(13, StaticRemoteKey, [InitContext, NodeContext, ChannelTypeContext],
329353
"Feature flags for `option_static_remotekey`.", set_static_remote_key_optional,
330354
set_static_remote_key_required);
331355
define_feature!(15, PaymentSecret, [InitContext, NodeContext, InvoiceContext],
@@ -388,6 +412,18 @@ pub type ChannelFeatures = Features<sealed::ChannelContext>;
388412
/// Features used within an invoice.
389413
pub type InvoiceFeatures = Features<sealed::InvoiceContext>;
390414

415+
/// Features used within the channel_type field in an OpenChannel message.
416+
///
417+
/// A channel is always of some known "type", describing the transaction formats used and the exact
418+
/// semantics of our interaction with our peer.
419+
///
420+
/// Note that because a channel is a specific type which is proposed by the opener and accepted by
421+
/// the counterparty, only required features are allowed here.
422+
///
423+
/// This is serialized differently from other feature types - it is not prefixed by a length, and
424+
/// thus must only appear inside a TLV where its length is known in advance.
425+
pub type ChannelTypeFeatures = Features<sealed::ChannelTypeContext>;
426+
391427
impl InitFeatures {
392428
/// Writes all features present up to, and including, 13.
393429
pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -442,6 +478,28 @@ impl InvoiceFeatures {
442478
}
443479
}
444480

481+
impl ChannelTypeFeatures {
482+
/// Constructs the implicit channel type based on the common supported types between us and our
483+
/// counterparty
484+
pub(crate) fn from_counterparty_init(counterparty_init: &InitFeatures) -> Self {
485+
let mut ret = counterparty_init.to_context_internal();
486+
// ChannelTypeFeatures must only contain required bits, so we OR the required forms of all
487+
// optional bits and then AND out the optional ones.
488+
for byte in ret.flags.iter_mut() {
489+
*byte |= (*byte & 0b10_10_10_10) >> 1;
490+
*byte &= 0b01_01_01_01;
491+
}
492+
ret
493+
}
494+
495+
/// Constructs a ChannelTypeFeatures with only static_remotekey set
496+
pub(crate) fn only_static_remote_key() -> Self {
497+
let mut ret = Self::empty();
498+
<sealed::ChannelTypeContext as sealed::StaticRemoteKey>::set_required_bit(&mut ret.flags);
499+
ret
500+
}
501+
}
502+
445503
impl ToBase32 for InvoiceFeatures {
446504
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
447505
// Explanation for the "4": the normal way to round up when dividing is to add the divisor
@@ -553,6 +611,25 @@ impl<T: sealed::Context> Features<T> {
553611
&self.flags
554612
}
555613

614+
fn write_be<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
615+
for f in self.flags.iter().rev() { // Swap back to big-endian
616+
f.write(w)?;
617+
}
618+
Ok(())
619+
}
620+
621+
fn from_be_bytes(mut flags: Vec<u8>) -> Features<T> {
622+
flags.reverse(); // Swap to little-endian
623+
Self {
624+
flags,
625+
mark: PhantomData,
626+
}
627+
}
628+
629+
pub(crate) fn supports_any_optional_bits(&self) -> bool {
630+
self.flags.iter().any(|&byte| (byte & 0b10_10_10_10) != 0)
631+
}
632+
556633
/// Returns true if this `Features` object contains unknown feature flags which are set as
557634
/// "required".
558635
pub fn requires_unknown_bits(&self) -> bool {
@@ -692,31 +769,44 @@ impl<T: sealed::ShutdownAnySegwit> Features<T> {
692769
self
693770
}
694771
}
695-
696-
impl<T: sealed::Context> Writeable for Features<T> {
697-
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
698-
(self.flags.len() as u16).write(w)?;
699-
for f in self.flags.iter().rev() { // Swap back to big-endian
700-
f.write(w)?;
772+
macro_rules! impl_feature_len_prefixed_write {
773+
($features: ident) => {
774+
impl Writeable for $features {
775+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
776+
(self.flags.len() as u16).write(w)?;
777+
self.write_be(w)
778+
}
779+
}
780+
impl Readable for $features {
781+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
782+
Ok(Self::from_be_bytes(Vec::<u8>::read(r)?))
783+
}
701784
}
702-
Ok(())
703785
}
704786
}
705-
706-
impl<T: sealed::Context> Readable for Features<T> {
787+
impl_feature_len_prefixed_write!(InitFeatures);
788+
impl_feature_len_prefixed_write!(ChannelFeatures);
789+
impl_feature_len_prefixed_write!(NodeFeatures);
790+
impl_feature_len_prefixed_write!(InvoiceFeatures);
791+
792+
// Because ChannelTypeFeatures only appears inside of TLVs, it doesn't have a length prefix when
793+
// serialized. Thus, we can't use `impl_feature_len_prefixed_write`, above, and have to write our
794+
// own serialization.
795+
impl Writeable for ChannelTypeFeatures {
796+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
797+
self.write_be(w)
798+
}
799+
}
800+
impl Readable for ChannelTypeFeatures {
707801
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
708-
let mut flags: Vec<u8> = Readable::read(r)?;
709-
flags.reverse(); // Swap to little-endian
710-
Ok(Self {
711-
flags,
712-
mark: PhantomData,
713-
})
802+
let v = io_extras::read_to_end(r)?;
803+
Ok(Self::from_be_bytes(v))
714804
}
715805
}
716806

717807
#[cfg(test)]
718808
mod tests {
719-
use super::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
809+
use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
720810
use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5};
721811

722812
#[test]
@@ -875,4 +965,15 @@ mod tests {
875965
let features_deserialized = InvoiceFeatures::from_base32(&features_as_u5s).unwrap();
876966
assert_eq!(features, features_deserialized);
877967
}
968+
969+
#[test]
970+
fn test_channel_type_mapping() {
971+
// If we map an InvoiceFeatures with StaticRemoteKey optional, it should map into a
972+
// required-StaticRemoteKey ChannelTypeFeatures.
973+
let init_features = InitFeatures::empty().set_static_remote_key_optional();
974+
let converted_features = ChannelTypeFeatures::from_counterparty_init(&init_features);
975+
assert_eq!(converted_features, ChannelTypeFeatures::only_static_remote_key());
976+
assert!(!converted_features.supports_any_optional_bits());
977+
assert!(converted_features.requires_static_remote_key());
978+
}
878979
}

0 commit comments

Comments
 (0)