Implement channel_type negotiation#1078
Conversation
87adcc0 to
49bf1be
Compare
Codecov Report
@@ Coverage Diff @@
## main #1078 +/- ##
=======================================
Coverage 90.46% 90.46%
=======================================
Files 68 68
Lines 35176 35176
=======================================
Hits 31822 31822
Misses 3354 3354 Continue to review full report at Codecov.
|
200c607 to
74930bd
Compare
arik-so
left a comment
There was a problem hiding this comment.
Looks good with the exception of minor nits.
| /// * [`NetGraphMsgHandler`] if given will update the [`NetworkGraph`] based on payment failures. | ||
| /// | ||
| /// [top-level documentation]: Self | ||
| /// [top-level documentation]: BackgroundProcessor |
There was a problem hiding this comment.
not really part of this PR, but whatever
There was a problem hiding this comment.
🤷♂️ not worth a separate pr for it.
| Some(script) => script.clone().into_inner(), | ||
| None => Builder::new().into_script(), | ||
| }), | ||
| channel_type: None, |
There was a problem hiding this comment.
unrelated to this diff, but if the message is to obtain an unprompted message to send, "generate" is probably a better prefix than "get"
There was a problem hiding this comment.
Yea, 🤷♂️, I mean its getting the open channel? I'm not gonna bother changing it unless you feel strongly.
| } | ||
|
|
||
| fn do_encoding_open_channel(random_bit: bool, shutdown: bool) { | ||
| fn do_encoding_open_channel(random_bit: bool, shutdown: bool, chan_type: bool) { |
There was a problem hiding this comment.
channel_type is a bitmap or feature set. The boolean should be named encode_channel_type or should_encode_channel_type or sth. along those lines.
There was a problem hiding this comment.
went with "incl" ie "include".
74930bd to
e271066
Compare
e271066 to
b7f1884
Compare
valentinewallace
left a comment
There was a problem hiding this comment.
Not 100% sure on some of these but didn't want to hold up feedback too long
| if channel_type.supports_unknown_bits() { | ||
| return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned())); | ||
| } |
There was a problem hiding this comment.
Atm, this would still allow an optional bit if the bit were static_remotekey, correct? Bit of an inexact error msg if so
Moreover, I think supports_unknown_bits needs to be modified for ChannelTypeFeatures in case the optional static_remotekey bit is set (in which case we'll still want to return true iiuc)
There was a problem hiding this comment.
Ugh, right, I was trying to be too clever by half. I rewrote it.
| { | ||
| // 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 { |
There was a problem hiding this comment.
From the spec for accept_channel:
if channel_type is set, and channel_type was set in open_channel, and they are not equal types:
MUST reject the channel.
I don't think we do this?
There was a problem hiding this comment.
We kinda do indirectly, but I made it explicit.
| } | ||
| channel_type.clone() | ||
| } else { | ||
| ChannelTypeFeatures::from_counterparty_init(&their_features) |
There was a problem hiding this comment.
I think if we're to include this line, and their Init supports but doesn't require static_remotekey, we should translate their features to require static_remotekey, since bit 13 should never be set in a ChannelTypeFeatures iiuc
b7f1884 to
105a6ab
Compare
105a6ab to
33dd6a2
Compare
|
Squashed without diff, will land after CI: |
Apparently at least rustc 1.48 doesn't support `Self` in doc links, so we make it explicit.
Its semantics are somewhat different from existing features, however not enough to merit a different struct entirely. Specifically, it only supports required features (if you send a channel_type, the counterparty has to accept it wholesale or try again, it cannot select only a subset of the flags) and it is serialized differently (only appearing in TLVs).
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.
33dd6a2 to
db2e7e7
Compare
|
Rebased on upstream, minor diff in the last commit to tweak serialization order, but realized I'd also missed the write side of the TLV entry - $ git range-diff 801d6e5256d6ac91d5d5668da1fa5a2b55303246..33dd6a224900cb5a1580cce26fc57a993529000b 0a31c12f85b55dd2b3a85e929a5c92086bc8842b..db2e7e75c451bba0f1d0b75aa62fa6212d008215
1: 54f37ac9e = 1: d0c3fb745 Fix `cargo doc` on older rustc
2: 85ed83c80 = 2: e847c87dc Add a ChannelTypeFeatures features object for the new channel_type
3: 153c2c7d6 = 3: b7a8dd4a1 Support de/ser of the new channel_type field in open_channel
4: 33dd6a224 ! 4: db2e7e75c Support send/recv'ing the new channel_type field in open_channel
@@ lightning/src/ln/channel.rs: use bitcoin::secp256k1::{Secp256k1,Signature};
+use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures};
use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
- use ln::script::ShutdownScript;
+ use ln::script::{self, ShutdownScript};
@@ lightning/src/ln/channel.rs: 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.
@@ lightning/src/ln/channel.rs: impl<Signer: Sign> Channel<Signer> {
}
}
-@@ lightning/src/ln/channel.rs: impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
+@@ lightning/src/ln/channel.rs: impl<Signer: Sign> Writeable for Channel<Signer> {
+ (7, self.shutdown_scriptpubkey, option),
+ (9, self.target_closing_feerate_sats_per_kw, option),
+ (11, self.monitor_pending_finalized_fulfills, vec_type),
++ (13, self.channel_type, required),
+ });
+ Ok(())
+@@ lightning/src/ln/channel.rs: 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;
+ let mut monitor_pending_finalized_fulfills = Some(Vec::new());
+ // 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());
@@ lightning/src/ln/channel.rs: impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K
(0, announcement_sigs, option),
(1, minimum_depth, option),
@@ lightning/src/ln/channel.rs: impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
- (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),
+ (11, monitor_pending_finalized_fulfills, vec_type),
++ (13, channel_type, option),
});
+ let chan_features = channel_type.as_ref().unwrap();
$ |
|
Will land post-0.0.103 given there's no reason to land this for 0.0.103 and we're really close to release-cut time so good to hold off on extra changes. |
This implements channel_type negotiation as defined at lightning/bolts#880, though it does not currently send the proposed feature bit from lightning/bolts#906. It is likely to be required for turbo channels, but if not will be required for anchor channels anyway.
It could use a test of some form, at least of the fallback behavior.