-
Notifications
You must be signed in to change notification settings - Fork 376
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 ChannelPhase
variants from ChannelManager
#3513
base: main
Are you sure you want to change the base?
Refactor ChannelPhase
variants from ChannelManager
#3513
Conversation
Reviewers: It is best to review each commit separately. I tried to avoid moving code or introducing indents whenever possible. I could do a follow-up to hide the enum entirely as mentioned in the PR description. I'm uncertain how valuable this would be. At very least it would prevent us from removing and inserting into hash maps when the channel id doesn't change. Zooming out, it would be nice to clearly define what belongs in |
0ee63dd
to
9a3315d
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3513 +/- ##
==========================================
+ Coverage 88.33% 88.35% +0.01%
==========================================
Files 149 149
Lines 112839 112951 +112
Branches 112839 112951 +112
==========================================
+ Hits 99672 99793 +121
+ Misses 10688 10684 -4
+ Partials 2479 2474 -5 ☔ View full report in Codecov by Sentry. |
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, introduce ChannelPhase::as_funded and ChannelPhase::as_funded_mut for use in ChannelManager when a Channel (to be later renamed FundedChannel) is needed.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, introduce ChannelPhase::is_funded for use in ChannelManager when a Channel (to be later renamed FundedChannel) needs to be tested for.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, rewrite ChannelManager's unfunded_channel_count method to use ChannelPhase::as_funded and a new ChannelPhase::as_unfunded_v2 method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::internal_tx_abort to use ChannelPhase::is_funded and a new ChannelPhase::as_unfunded_v2_mut method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::signer_unblocked to use ChannelPhase::as_funded and a new method on ChannelPhase dispatching to each variant's signer_maybe_unblocked method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::peer_disconnected to use ChannelPhase::as_funded_mut and a new ChannelPhase::is_resumable method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::peer_connected to use ChannelPhase::as_funded_mut and a new ChannelPhase::maybe_get_open_channel method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::handle_error to use a new ChannelPhase::maybe_handle_error_without_close.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager::timer_tick_occurred to use ChannelPhase::as_funded_mut and a new ChannelPhase::unfunded_context_mut method.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager methods to use ChannelPhase::as_unfunded_v2_mut and ChannelPhase::into_unfunded_v2 methods.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update the convert_chan_phase_err macro to use ChannelPhase::as_funded_mut instead.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, update ChannelManager methods to use methods on ChannelPhase for obtaining the appropriate V1 channel types.
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, define a conversion from Channel (to be renamed FundedChannel) to ChannelPhase (to be renamed Channel).
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, define a conversion from OutboundV1Channel to ChannelPhase (to be renamed Channel).
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, define a conversion from InboundV1Channel to ChannelPhase (to be renamed Channel).
Exposing ChannelPhase in ChannelManager has led to verbose match statements, which need to be modified each time a ChannelPhase is added. Making ChannelPhase an implementation detail of Channel would help avoid this. As a step in this direction, define a conversion from PendingV2Channel to ChannelPhase (to be renamed Channel).
9a3315d
to
786cf37
Compare
Can rebase as 3498 is merged. |
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 generally LGTM and the renames are great.
Thanks for splitting it up like this. Just left some minor remarks/comments that could probably all be NO_OPs.
lightning/src/ln/channel.rs
Outdated
ChannelPhase::Funded(_) => false, | ||
ChannelPhase::UnfundedOutboundV1(chan) => chan.is_resumable(), | ||
ChannelPhase::UnfundedInboundV1(_) => false, | ||
ChannelPhase::UnfundedV2(_) => false, |
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 suppose I'd need to look at introducing is_resumable()
to PendingV2Chan
if possible.
@@ -8979,6 +9011,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider { | |||
/// If we receive an error message, it may only be a rejection of the channel type we tried, | |||
/// not of our ability to open any channel at all. Thus, on error, we should first call this | |||
/// and see if we get a new `OpenChannelV2` message, otherwise the channel is failed. | |||
#[cfg(dual_funding)] |
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.
Do we have to introduce the cfg flags again? I think with #3485 we wanted to only have them where necessary.
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.
Discussed offline. This is needed to avoid a compilation error since the calls site needs OpenChannelMessage::V2
.
process_unfunded_channel_tick!(peer_state, chan, pending_msg_events) | ||
None => { | ||
phase.context_mut().maybe_expire_prev_config(); | ||
let unfunded_context = phase.unfunded_context_mut().expect("channel should be unfunded"); |
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.
Nice that we got rid of the macro, but sad that we need this expect
. That's okay, 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.
Yeah, the only way to really avoid this is to have a method returning an enum that has Funded
and Unfunded
variants, where the latter gives the UnfundedChannelContext
. I'm not necessarily opposed to the idea (and maybe it would be useful elsewhere?), but I opted for a minimal change initially.
In preparation for hiding ChannelPhase inside a Channel type, rename Channel to FundedChannel.
In preparation for hiding ChannelPhase inside a Channel type, rename ChannelPhase to Channel.
786cf37
to
1775d64
Compare
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.
Pushed some doclink changes caught by CI.
@@ -8979,6 +9011,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider { | |||
/// If we receive an error message, it may only be a rejection of the channel type we tried, | |||
/// not of our ability to open any channel at all. Thus, on error, we should first call this | |||
/// and see if we get a new `OpenChannelV2` message, otherwise the channel is failed. | |||
#[cfg(dual_funding)] |
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.
Discussed offline. This is needed to avoid a compilation error since the calls site needs OpenChannelMessage::V2
.
process_unfunded_channel_tick!(peer_state, chan, pending_msg_events) | ||
None => { | ||
phase.context_mut().maybe_expire_prev_config(); | ||
let unfunded_context = phase.unfunded_context_mut().expect("channel should be unfunded"); |
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, the only way to really avoid this is to have a method returning an enum that has Funded
and Unfunded
variants, where the latter gives the UnfundedChannelContext
. I'm not necessarily opposed to the idea (and maybe it would be useful elsewhere?), but I opted for a minimal change initially.
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.
LGTM, fine piece-by-piece work!
Some general comments:
There are a few match
es with 2 arms: Some
and None
(pre-change: FundedChannel
and _
): the if let Some()
construct is probably more appropriate, but I do understand that you tried to keep changes to minimal, which is fine.
I've checked FundedChannel
usage, outside of channel.rs
it is only used in channelmanager.rs
, in about 12 places, mostly as parameter type for methods. I think those are fine at this point, but maybe you should have a look yourself.
pub fn is_funded(&self) -> bool { | ||
self.as_funded().is_some() | ||
} |
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.
nit: for a minimal more efficiency, could be unrolled to:
pub fn is_funded(&self) -> bool { | |
self.as_funded().is_some() | |
} | |
pub fn is_funded(&self) -> bool { | |
matches!(self, Channel::Funded(_channel)) | |
} |
Exposing
ChannelPhase
inChannelManager
has led to verbosematch
statements, which need to be modified each time aChannelPhase
is added. MakingChannelPhase
an implementation detail ofChannel
would help avoidthis.
This PR is a step in that direction by removing direct use of
ChannelPhase
variants fromChannelManager
. Instead, various methods are added toChannelPhase
in order to obtain the underlying structs held by each variant.Channel
is also renamed toFundedChannel
such thatChannelPhase
can be renamed toChannel
. A follow-up PR will hideChannelPhase
insideChannel
, if desired.Based on #3498.