-
Notifications
You must be signed in to change notification settings - Fork 411
Implement channel closing for block_disconnected on ChainListener + test #47
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
Implement channel closing for block_disconnected on ChainListener + test #47
Conversation
src/ln/channelmanager.rs
Outdated
for channel in closing_channel { | ||
match self.close_channel(&channel) { | ||
Ok(_msg) => {} | ||
Err(_e) => {} //TODO: if error is stir up by pending HTLC, after timer, try to call close_channel again ? |
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'm thinking we have 2 way to handle errors (like pending HTLCs) on channel close: 1/ we return a vec of tuple (channel_id, false) to caller of block_disconnected, 2/ we push a timer on event with a new call to block_disconnected. Former is cumbersome for the caller, latter for dealing internally with timer events.
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 think we need to be more aggressive. Generally, when dealing with a confirmation-tx-unconf error, we'd really prefer to force-close and initiate the race instead of letting our counterparty participate in the shutdown, as its more of a last-ditch thing. Should be able to just do a force_shutdown() and remove the channel from our channels maps, I think.
src/ln/channel.rs
Outdated
@@ -1844,6 +1844,15 @@ impl Channel { | |||
self.channel_update_count | |||
} | |||
|
|||
pub fn get_channel_id(&self) -> Uint256 { |
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 is redundant with channel_id(&self), a few lines up.
src/ln/channel.rs
Outdated
} | ||
|
||
#[test] | ||
pub fn get_channel_state(&self) -> u32 { |
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.
Hmm, I'd prefer this not be exposed, especially given we may want to change the enum values at some point without having to recall that the tests use it. It should be easy to instead test for an outbound Shutdown message having been generated to see the close occurring instead of getting the channel state explicitly.
src/ln/channelmanager.rs
Outdated
for channel in closing_channel { | ||
match self.close_channel(&channel) { | ||
Ok(_msg) => {} | ||
Err(_e) => {} //TODO: if error is stir up by pending HTLC, after timer, try to call close_channel again ? |
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 think we need to be more aggressive. Generally, when dealing with a confirmation-tx-unconf error, we'd really prefer to force-close and initiate the race instead of letting our counterparty participate in the shutdown, as its more of a last-ditch thing. Should be able to just do a force_shutdown() and remove the channel from our channels maps, I think.
1e5c0cb
to
286cc3a
Compare
@@ -231,7 +231,7 @@ const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 | | |||
|
|||
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking | |||
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like | |||
// calling get_channel_id() before we're set up or things like get_outbound_funding_signed on an | |||
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an |
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.
The reason at first why I added get_channel_id(), but I think that channel_id() is that.
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.
Cool, looking good!
src/ln/channelmanager.rs
Outdated
for channel in channel_state.by_id.values_mut() { | ||
if channel.block_disconnected(header) { | ||
//TODO Close channel here | ||
channel.force_shutdown(); |
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.
You need to broadcast the transactions returned here.
src/ln/channelmanager.rs
Outdated
//TODO Close channel here | ||
channel.force_shutdown(); | ||
if let Some(chan_id) = channel.get_short_channel_id() { | ||
closed_channel.push(chan_id.clone()); |
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.
You should be able to remove this by changing the loop to a retain().
286cc3a
to
11adae4
Compare
Updated, spec was unclear on what doing in this case, what theoretically prevent us to just "freeze" the channel and put it again alive if it gets again enough confirmations ? ( |
src/ln/channelmanager.rs
Outdated
fn block_disconnected(&self, header: &BlockHeader) { | ||
let mut closed_channel = Vec::new(); |
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 think you can skip this, too, if you switch back to the borrow_parts() (since borrow_parts() is used to let you get around the borrow checker for stuff like this :))
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.
Sorry are you sure it works with closure? I get a E500 or E0499 each time, I'm still a beginner in magic spells against borrowck
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 diff works for me (though no guarantees about older rustcs, lets see what travis says): https://0bin.net/paste/at3mwfdpXIeugIQ4#X62nrP-X/OYnkLEJ75jrbpR9FRY8DxcOudBzraNDW98
11adae4
to
1b8544f
Compare
Updated, thanks, get it works on 1.22 and my 1.28-nightly! |
I implemented taking care of potential deadlock between channel_state and call to close_channel. Test is really basic, creating a channel, disconnecting blocks and checking it going to LocalShutdownSent state.