Skip to content

Commit

Permalink
Support send/recv'ing the new channel_type field in open_channel
Browse files Browse the repository at this point in the history
This implements the channel type negotiation, though as we currently
only support channels with only static_remotekey set, it doesn't
implement the negotiation explicitly.
  • Loading branch information
TheBlueMatt committed Sep 17, 2021
1 parent 4144324 commit 87adcc0
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
36 changes: 35 additions & 1 deletion lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1,Signature};
use bitcoin::secp256k1;

use ln::{PaymentPreimage, PaymentHash};
use ln::features::{ChannelFeatures, InitFeatures};
use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures};
use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::script::ShutdownScript;
Expand Down Expand Up @@ -540,6 +540,9 @@ pub(super) struct Channel<Signer: Sign> {
// is fine, but as a sanity check in our failure to generate the second claim, we check here
// that the original was a claim, and that we aren't now trying to fulfill a failed HTLC.
historical_inbound_htlc_fulfills: HashSet<u64>,

/// This channel's type, as negotiated during channel open
channel_type: ChannelTypeFeatures,
}

#[cfg(any(test, feature = "fuzztarget"))]
Expand Down Expand Up @@ -761,6 +764,11 @@ impl<Signer: Sign> Channel<Signer> {

#[cfg(any(test, feature = "fuzztarget"))]
historical_inbound_htlc_fulfills: HashSet::new(),

// We currently only actually support one channel type, and so send there here with no
// attempts to retry on error messages. When we support more we'll need fallback
// support (assuming we want to support old types).
channel_type: ChannelTypeFeatures::known(),
})
}

Expand Down Expand Up @@ -789,6 +797,23 @@ impl<Signer: Sign> Channel<Signer> {
where K::Target: KeysInterface<Signer = Signer>,
F::Target: FeeEstimator
{
// First check the channel type is known, failing before we do anything else if we don't
// support this channel type.
let channel_type = if let Some(channel_type) = &msg.channel_type {
if channel_type.supports_unknown_bits() {
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
}
if channel_type.requires_unknown_bits() {
return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
}
channel_type.clone()
} else {
ChannelTypeFeatures::from_counterparty_init(&their_features)
};
if !channel_type.supports_static_remote_key() {
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
}

let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis);
let pubkeys = holder_signer.pubkeys().clone();
let counterparty_pubkeys = ChannelPublicKeys {
Expand Down Expand Up @@ -1028,6 +1053,8 @@ impl<Signer: Sign> Channel<Signer> {

#[cfg(any(test, feature = "fuzztarget"))]
historical_inbound_htlc_fulfills: HashSet::new(),

channel_type,
};

Ok(chan)
Expand Down Expand Up @@ -4217,6 +4244,7 @@ impl<Signer: Sign> Channel<Signer> {
Some(script) => script.clone().into_inner(),
None => Builder::new().into_script(),
}),
channel_type: Some(self.channel_type.clone()),
}
}

Expand Down Expand Up @@ -5406,13 +5434,17 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>

let mut announcement_sigs = None;
let mut target_closing_feerate_sats_per_kw = None;
// Prior to supporting channel type negotiation, all of our channels were static_remotekey
// only, so we default to that if none was written.
let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
read_tlv_fields!(reader, {
(0, announcement_sigs, option),
(1, minimum_depth, option),
(3, counterparty_selected_channel_reserve_satoshis, option),
(5, config, option), // Note that if none is provided we will *not* overwrite the existing one.
(7, shutdown_scriptpubkey, option),
(9, target_closing_feerate_sats_per_kw, option),
(11, channel_type, option),
});

let mut secp_ctx = Secp256k1::new();
Expand Down Expand Up @@ -5506,6 +5538,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>

#[cfg(any(test, feature = "fuzztarget"))]
historical_inbound_htlc_fulfills,

channel_type: channel_type.unwrap(),
})
}
}
Expand Down
10 changes: 8 additions & 2 deletions lightning/src/ln/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use bitcoin::secp256k1;
use bitcoin::blockdata::script::Script;
use bitcoin::hash_types::{Txid, BlockHash};

use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};

use prelude::*;
use core::{cmp, fmt};
Expand Down Expand Up @@ -148,6 +148,10 @@ pub struct OpenChannel {
pub channel_flags: u8,
/// Optionally, a request to pre-set the to-sender output's scriptPubkey for when we collaboratively close
pub shutdown_scriptpubkey: OptionalField<Script>,
/// The channel type that this channel will represent. If none is set, we derive the channel
/// type from the intersection of our feature bits with our counterparty's feature bits from
/// the Init message.
pub channel_type: Option<ChannelTypeFeatures>,
}

/// An accept_channel message to be sent or received from a peer
Expand Down Expand Up @@ -1162,7 +1166,9 @@ impl_writeable_msg!(OpenChannel, {
first_per_commitment_point,
channel_flags,
shutdown_scriptpubkey
}, {});
}, {
(1, channel_type, option),
});

impl_writeable_msg!(RevokeAndACK, {
channel_id,
Expand Down

0 comments on commit 87adcc0

Please sign in to comment.