-
Notifications
You must be signed in to change notification settings - Fork 382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor ChannelTransactionParameters
into FundingScope
#3604
base: main
Are you sure you want to change the base?
Refactor ChannelTransactionParameters
into FundingScope
#3604
Conversation
@wpaulino This primarily moves fields from The drawback is we'd be duplicating fields that wouldn't change. But this seems better than duplicating fields that would change and risk having inconsistent data. Also, it could prevent us from needing to worry about changing other uses of What are your thoughts? |
I was thinking we could deprecate the funding scope related fields from |
Yeah, this PR takes that approach. But when removing the fields we'd need to update all uses to take both For instance, writing an There's also I haven't looked exhaustively to see all usages, but it seems simpler to keep |
Hm, I'm not opposed to always writing As for |
Here's the alternative approach: https://github.com/jkczyz/rust-lightning/tree/2025-02-channel-funding-pubkeys-alt |
Yeah this looks pretty simple, and would also allow us to handle transitioning to new channel types in a splice since it already tracks the channel type features. I don't think the duplicate data is all that bad here once we have multiple scopes since it will eventually go away when the splice confirms. We should at least be able to avoid persisting the duplicate data, if we choose to, by cloning it from the "main" (currently confirmed) scope when reading. Thoughts on either of these approaches @TheBlueMatt? |
@TheBlueMatt Added some more commits to the alternative branch after pairing with @wpaulino yesterday. They move |
Discussed this being supersceded by an alternative that tries to keep signer operations (across many splice versions) together as one call. |
e788ac1
to
df840cb
Compare
Rather than moving relevant fields of ChannelTransactionParameters to FundingScope, move the entire struct there instead. This prevents API churn wherever ChannelTransactionParameters is used, which otherwise would need a FundingScope in addition.
Since the funding transactions changes for each new FudningScope, include it there instead of ChannelContext.
df840cb
to
aff70ae
Compare
FundingScope
ChannelTransactionParameters
into FundingScope
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3604 +/- ##
==========================================
- Coverage 88.60% 88.59% -0.02%
==========================================
Files 151 151
Lines 118409 118404 -5
Branches 118409 118404 -5
==========================================
- Hits 104918 104900 -18
+ Misses 10972 10968 -4
- Partials 2519 2536 +17 ☔ View full report in Codecov by Sentry. |
Updated the branch to use the alternative version. See updated PR description for details. |
339e0ca
to
a55149f
Compare
let keys_data = keys_data.ok_or(DecodeError::InvalidValue)?; | ||
let holder_signer = signer_provider.read_chan_signer(&keys_data)?; | ||
(holder_signer.channel_keys_id(), holder_signer) | ||
return Err(DecodeError::InvalidValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a pending release note that we no longer support upgrading from versions of LDK prior to 0.0.113 (Dec 16, 2022). Once we include that, we should probably open an issue because there's certainly a lot of fields we can start making required now 🎉.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pending changelog added and opened #3625.
lightning/src/ln/chan_utils.rs
Outdated
@@ -993,6 +1010,7 @@ impl Readable for ChannelTransactionParameters { | |||
(8, funding_outpoint, option), | |||
(10, _legacy_deserialization_prevention_marker, option), | |||
(11, channel_type_features, option), | |||
(13, channel_value_satoshis, (default_value, 0)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bleh, having a spurious 0 in these seems like it'll cause issues. Shouldn't we make it an Option
so that we can check accesses for correctness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, so currently this needs to be set by the caller. We could have ChannelTransactionParameters
use ReadableArgs
and pass it in, checking as you described, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer the ReadableArgs
over having to deal with the option everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to use ReadableArgs
in a fixup. This required updating the serialization macros since other structs hold ChannelTransactionParameters
. It was a small change, but please check to see if how I'm using it is sane.
@@ -882,7 +882,9 @@ pub struct ChannelTransactionParameters { | |||
pub funding_outpoint: Option<chain::transaction::OutPoint>, | |||
/// This channel's type, as negotiated during channel open. For old objects where this field | |||
/// wasn't serialized, it will default to static_remote_key at deserialization. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're providing these to the signer on every call now (and there's so much redundant data) I wonder if (I guess it could happen when we do splicing) we shouldn't have some partial-comparator for these that just checks that two of them are equal for the fields that shouldn't change across a splice?
CI is sad |
Fixed now, I think. Will make add pending CHANGELOG item in a bit. For now, PTAL. |
888e658
to
38aad8e
Compare
Changes LGTM, but CI is still quite sad. |
38aad8e
to
1682e84
Compare
lightning/src/ln/channel.rs
Outdated
let mut _keys_data = None; | ||
if ver <= 2 { | ||
// Read the serialize signer bytes. We'll choose to deserialize them or not based on whether | ||
// the `channel_keys_id` TLV is present below. | ||
// Read the serialize signer bytes. These are no longer used as of version 0.2.0. | ||
let keys_len: u32 = Readable::read(reader)?; | ||
keys_data = Some(Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE))); | ||
while keys_data.as_ref().unwrap().len() != keys_len as usize { | ||
_keys_data = Some(Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE))); | ||
while _keys_data.as_ref().unwrap().len() != keys_len as usize { | ||
// Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys | ||
let mut data = [0; 1024]; | ||
let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.as_ref().unwrap().len())]; | ||
let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - _keys_data.as_ref().unwrap().len())]; | ||
reader.read_exact(read_slice)?; | ||
keys_data.as_mut().unwrap().extend_from_slice(read_slice); | ||
_keys_data.as_mut().unwrap().extend_from_slice(read_slice); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to remove all of this now, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, done.
Feel free to squash |
1682e84
to
f8877ff
Compare
InMemorySigner no longer holds channel_value_satoshis and channel_parameters. Instead of writing 0 and None, respectively, drop (de-)serialization support entirely since InMemorySigner hasn't been serialized since SERIALIZATION_VERSION 2.
Since channel_value_satoshis is needed by the signer and may change for each new FundingScope, included it in ChannelTransactionParameters so it can be passed to each signer call in the upcoming commits.
Now that ChannelTransactionParameters are in FundingScope, channel_value_satoshis can be dropped from the latter.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, pass the entire parameters when calling each method on EcdsaChannelSigner. This will remove the need for ChannelSigner::provide_channel_parameters. Instead, the parameters from the FundingScope will be passed in to each method. This simplifies the interaction with a ChannelSigner when needing to be called for more than one FundingScope, which will be the case for pending splices and RBF attempts.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, InMemorySigner no longer needs a copy. Remove uses of the copy from sign_counterparty_payment_input.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, InMemorySigner no longer needs a copy. Remove indirect uses of the copy from TestChannelSigner.
Now that the copy of ChannelTransactionParameters is no longer used by InMemorySigner, remove it and all remaining uses. Since it was set by ChannelSigner::provide_channel_parameters, this method is no longer needed and can also be removed.
Now that channel_value_satoshis has been moved to ChannelTransactionParameters, it no longer needs to be used when deriving a signer. This is a breaking API change, though InMemorySigner did not make use of channel_value_satoshis when being derived.
The custom derive_channel_signer methods on AnchorDescriptor and HTLCDescriptor simply delegate to the passed SignerProvider now that providing ChannelTransactionParameters is no longer needed. Drop these methods and replace them with the method bodies at the call sites.
f8877ff
to
39bcc54
Compare
Squashed with the following changes: diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index cef3a990c..87f5cff1b 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -10260,7 +10260,6 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
}
}
-const MAX_ALLOC_SIZE: usize = 64*1024;
impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c ChannelTypeFeatures)> for FundedChannel<SP>
where
ES::Target: EntropySource,
@@ -10293,20 +10292,6 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
let latest_monitor_update_id = Readable::read(reader)?;
- let mut _keys_data = None;
- if ver <= 2 {
- // Read the serialize signer bytes. These are no longer used as of version 0.2.0.
- let keys_len: u32 = Readable::read(reader)?;
- _keys_data = Some(Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE)));
- while _keys_data.as_ref().unwrap().len() != keys_len as usize {
- // Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
- let mut data = [0; 1024];
- let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - _keys_data.as_ref().unwrap().len())];
- reader.read_exact(read_slice)?;
- _keys_data.as_mut().unwrap().extend_from_slice(read_slice);
- }
- }
-
// Read the old serialization for shutdown_pubkey, preferring the TLV field later if set.
let mut shutdown_scriptpubkey = match <PublicKey as Readable>::read(reader) {
Ok(pubkey) => Some(ShutdownScript::new_p2wpkh_from_pubkey(pubkey)), |
Continues the work of #3592 by moving fields related to the funding transaction into
FundingScope
.This includes fields fromChannelContext
for the funding transaction andChannelTransactionParameters
for the funding outpoint and pubkeys.This primarily involves moving the entire
ChannelTransactionParameters
intoFundingScope
andchannel_value_satoshis
intoChannelTransactionParameters
. The latter result in less API churn at the cost of duplicating parameters that don't change across eachFundingScope
. To that end, this PR also updates theEcdsaChannelSigner
to takeChannelTransactionParameters
which removes the need forChannelSigner::provide_channel_parameters
.Since
ChannelTransactionParameters
containschannel_value_satoshis
, implementation likeInMemorySigner
no longer need it. Thus, theNodeSigner
trait is updated to no longer take the value when deriving signers, which is a breaking change.