Skip to content

Commit 569f906

Browse files
authored
Merge pull request #3539 from TheBlueMatt/2025-01-3513-followups
Further decouple ChannelManager from Channel state somewhat
2 parents 8d8b4ea + bece44c commit 569f906

File tree

2 files changed

+118
-122
lines changed

2 files changed

+118
-122
lines changed

lightning/src/ln/channel.rs

+37-20
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,13 @@ pub(super) struct ReestablishResponses {
933933
pub shutdown_msg: Option<msgs::Shutdown>,
934934
}
935935

936+
/// The first message we send to our peer after connection
937+
pub(super) enum ReconnectionMsg {
938+
Reestablish(msgs::ChannelReestablish),
939+
Open(OpenChannelMessage),
940+
None,
941+
}
942+
936943
/// The result of a shutdown that should be handled.
937944
#[must_use]
938945
pub(crate) struct ShutdownResult {
@@ -1266,8 +1273,7 @@ impl<SP: Deref> Channel<SP> where
12661273
})
12671274
},
12681275
ChannelPhase::UnfundedInboundV1(chan) => {
1269-
let logger = WithChannelContext::from(logger, &chan.context, None);
1270-
let accept_channel = chan.signer_maybe_unblocked(&&logger);
1276+
let accept_channel = chan.signer_maybe_unblocked(logger);
12711277
Some(SignerResumeUpdates {
12721278
commitment_update: None,
12731279
revoke_and_ack: None,
@@ -1286,51 +1292,62 @@ impl<SP: Deref> Channel<SP> where
12861292
}
12871293
}
12881294

1289-
pub fn is_resumable(&self) -> bool {
1290-
match &self.phase {
1295+
/// Should be called when the peer is disconnected. Returns true if the channel can be resumed
1296+
/// when the peer reconnects (via [`Self::peer_connected_get_handshake`]). If not, the channel
1297+
/// must be immediately closed.
1298+
pub fn peer_disconnected_is_resumable<L: Deref>(&mut self, logger: &L) -> bool where L::Target: Logger {
1299+
match &mut self.phase {
12911300
ChannelPhase::Undefined => unreachable!(),
1292-
ChannelPhase::Funded(_) => false,
1301+
ChannelPhase::Funded(chan) => chan.remove_uncommitted_htlcs_and_mark_paused(logger).is_ok(),
1302+
// If we get disconnected and haven't yet committed to a funding
1303+
// transaction, we can replay the `open_channel` on reconnection, so don't
1304+
// bother dropping the channel here. However, if we already committed to
1305+
// the funding transaction we don't yet support replaying the funding
1306+
// handshake (and bailing if the peer rejects it), so we force-close in
1307+
// that case.
12931308
ChannelPhase::UnfundedOutboundV1(chan) => chan.is_resumable(),
12941309
ChannelPhase::UnfundedInboundV1(_) => false,
12951310
ChannelPhase::UnfundedV2(_) => false,
12961311
}
12971312
}
12981313

1299-
pub fn maybe_get_open_channel<L: Deref>(
1314+
/// Should be called when the peer re-connects, returning an initial message which we should
1315+
/// send our peer to begin the channel reconnection process.
1316+
pub fn peer_connected_get_handshake<L: Deref>(
13001317
&mut self, chain_hash: ChainHash, logger: &L,
1301-
) -> Option<OpenChannelMessage> where L::Target: Logger {
1318+
) -> ReconnectionMsg where L::Target: Logger {
13021319
match &mut self.phase {
13031320
ChannelPhase::Undefined => unreachable!(),
1304-
ChannelPhase::Funded(_) => None,
1321+
ChannelPhase::Funded(chan) =>
1322+
ReconnectionMsg::Reestablish(chan.get_channel_reestablish(logger)),
13051323
ChannelPhase::UnfundedOutboundV1(chan) => {
1306-
let logger = WithChannelContext::from(logger, &chan.context, None);
1307-
chan.get_open_channel(chain_hash, &&logger)
1308-
.map(|msg| OpenChannelMessage::V1(msg))
1324+
chan.get_open_channel(chain_hash, logger)
1325+
.map(|msg| ReconnectionMsg::Open(OpenChannelMessage::V1(msg)))
1326+
.unwrap_or(ReconnectionMsg::None)
13091327
},
13101328
ChannelPhase::UnfundedInboundV1(_) => {
13111329
// Since unfunded inbound channel maps are cleared upon disconnecting a peer,
13121330
// they are not persisted and won't be recovered after a crash.
13131331
// Therefore, they shouldn't exist at this point.
13141332
debug_assert!(false);
1315-
None
1333+
ReconnectionMsg::None
13161334
},
13171335
#[cfg(dual_funding)]
13181336
ChannelPhase::UnfundedV2(chan) => {
13191337
if chan.context.is_outbound() {
1320-
Some(OpenChannelMessage::V2(chan.get_open_channel_v2(chain_hash)))
1338+
ReconnectionMsg::Open(OpenChannelMessage::V2(
1339+
chan.get_open_channel_v2(chain_hash)
1340+
))
13211341
} else {
13221342
// Since unfunded inbound channel maps are cleared upon disconnecting a peer,
13231343
// they are not persisted and won't be recovered after a crash.
13241344
// Therefore, they shouldn't exist at this point.
13251345
debug_assert!(false);
1326-
None
1346+
ReconnectionMsg::None
13271347
}
13281348
},
13291349
#[cfg(not(dual_funding))]
1330-
ChannelPhase::UnfundedV2(_) => {
1331-
debug_assert!(false);
1332-
None
1333-
},
1350+
ChannelPhase::UnfundedV2(_) => ReconnectionMsg::None,
13341351
}
13351352
}
13361353

@@ -6118,7 +6135,7 @@ impl<SP: Deref> FundedChannel<SP> where
61186135
/// No further message handling calls may be made until a channel_reestablish dance has
61196136
/// completed.
61206137
/// May return `Err(())`, which implies [`ChannelContext::force_shutdown`] should be called immediately.
6121-
pub fn remove_uncommitted_htlcs_and_mark_paused<L: Deref>(&mut self, logger: &L) -> Result<(), ()> where L::Target: Logger {
6138+
fn remove_uncommitted_htlcs_and_mark_paused<L: Deref>(&mut self, logger: &L) -> Result<(), ()> where L::Target: Logger {
61226139
assert!(!matches!(self.context.channel_state, ChannelState::ShutdownComplete));
61236140
if self.context.channel_state.is_pre_funded_state() {
61246141
return Err(())
@@ -8045,7 +8062,7 @@ impl<SP: Deref> FundedChannel<SP> where
80458062

80468063
/// May panic if called on a channel that wasn't immediately-previously
80478064
/// self.remove_uncommitted_htlcs_and_mark_paused()'d
8048-
pub fn get_channel_reestablish<L: Deref>(&mut self, logger: &L) -> msgs::ChannelReestablish where L::Target: Logger {
8065+
fn get_channel_reestablish<L: Deref>(&mut self, logger: &L) -> msgs::ChannelReestablish where L::Target: Logger {
80498066
assert!(self.context.channel_state.is_peer_disconnected());
80508067
assert_ne!(self.context.cur_counterparty_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER);
80518068
// This is generally the first function which gets called on any given channel once we're

lightning/src/ln/channelmanager.rs

+81-102
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use crate::events::{self, Event, EventHandler, EventsProvider, InboundChannelFun
4848
use crate::ln::inbound_payment;
4949
use crate::ln::types::ChannelId;
5050
use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
51-
use crate::ln::channel::{self, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext};
51+
use crate::ln::channel::{self, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, ReconnectionMsg, InboundV1Channel, WithChannelContext};
5252
#[cfg(any(dual_funding, splicing))]
5353
use crate::ln::channel::PendingV2Channel;
5454
use crate::ln::channel_state::ChannelDetails;
@@ -6540,12 +6540,11 @@ where
65406540
chan.context_mut().maybe_expire_prev_config();
65416541
let unfunded_context = chan.unfunded_context_mut().expect("channel should be unfunded");
65426542
if unfunded_context.should_expire_unfunded_channel() {
6543-
let context = chan.context();
6543+
let context = chan.context_mut();
65446544
let logger = WithChannelContext::from(&self.logger, context, None);
65456545
log_error!(logger,
65466546
"Force-closing pending channel with ID {} for not establishing in a timely manner",
65476547
context.channel_id());
6548-
let context = chan.context_mut();
65496548
let mut close_res = context.force_shutdown(false, ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) });
65506549
locked_close_channel!(self, peer_state, context, close_res);
65516550
shutdown_channels.push(close_res);
@@ -9401,49 +9400,65 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
94019400

94029401
// Returns whether we should remove this channel as it's just been closed.
94039402
let unblock_chan = |chan: &mut Channel<SP>, pending_msg_events: &mut Vec<MessageSendEvent>| -> Option<ShutdownResult> {
9403+
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
94049404
let node_id = chan.context().get_counterparty_node_id();
9405-
match (chan.signer_maybe_unblocked(self.chain_hash, &self.logger), chan.as_funded()) {
9406-
(Some(msgs), Some(funded_chan)) => {
9407-
let cu_msg = msgs.commitment_update.map(|updates| events::MessageSendEvent::UpdateHTLCs {
9405+
if let Some(msgs) = chan.signer_maybe_unblocked(self.chain_hash, &&logger) {
9406+
if let Some(msg) = msgs.open_channel {
9407+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
94089408
node_id,
9409-
updates,
9409+
msg,
94109410
});
9411-
let raa_msg = msgs.revoke_and_ack.map(|msg| events::MessageSendEvent::SendRevokeAndACK {
9411+
}
9412+
if let Some(msg) = msgs.funding_created {
9413+
pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
94129414
node_id,
94139415
msg,
94149416
});
9415-
match (cu_msg, raa_msg) {
9416-
(Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::CommitmentFirst => {
9417-
pending_msg_events.push(cu);
9418-
pending_msg_events.push(raa);
9419-
},
9420-
(Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::RevokeAndACKFirst => {
9421-
pending_msg_events.push(raa);
9422-
pending_msg_events.push(cu);
9423-
},
9424-
(Some(cu), _) => pending_msg_events.push(cu),
9425-
(_, Some(raa)) => pending_msg_events.push(raa),
9426-
(_, _) => {},
9427-
}
9428-
if let Some(msg) = msgs.funding_signed {
9429-
pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
9430-
node_id,
9431-
msg,
9432-
});
9433-
}
9417+
}
9418+
if let Some(msg) = msgs.accept_channel {
9419+
pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
9420+
node_id,
9421+
msg,
9422+
});
9423+
}
9424+
let cu_msg = msgs.commitment_update.map(|updates| events::MessageSendEvent::UpdateHTLCs {
9425+
node_id,
9426+
updates,
9427+
});
9428+
let raa_msg = msgs.revoke_and_ack.map(|msg| events::MessageSendEvent::SendRevokeAndACK {
9429+
node_id,
9430+
msg,
9431+
});
9432+
match (cu_msg, raa_msg) {
9433+
(Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::CommitmentFirst => {
9434+
pending_msg_events.push(cu);
9435+
pending_msg_events.push(raa);
9436+
},
9437+
(Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::RevokeAndACKFirst => {
9438+
pending_msg_events.push(raa);
9439+
pending_msg_events.push(cu);
9440+
},
9441+
(Some(cu), _) => pending_msg_events.push(cu),
9442+
(_, Some(raa)) => pending_msg_events.push(raa),
9443+
(_, _) => {},
9444+
}
9445+
if let Some(msg) = msgs.funding_signed {
9446+
pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
9447+
node_id,
9448+
msg,
9449+
});
9450+
}
9451+
if let Some(msg) = msgs.closing_signed {
9452+
pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
9453+
node_id,
9454+
msg,
9455+
});
9456+
}
9457+
if let Some(funded_chan) = chan.as_funded() {
94349458
if let Some(msg) = msgs.channel_ready {
94359459
send_channel_ready!(self, pending_msg_events, funded_chan, msg);
94369460
}
9437-
if let Some(msg) = msgs.closing_signed {
9438-
pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
9439-
node_id,
9440-
msg,
9441-
});
9442-
}
94439461
if let Some(broadcast_tx) = msgs.signed_closing_tx {
9444-
let channel_id = funded_chan.context.channel_id();
9445-
let counterparty_node_id = funded_chan.context.get_counterparty_node_id();
9446-
let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(channel_id), None);
94479462
log_info!(logger, "Broadcasting closing tx {}", log_tx!(broadcast_tx));
94489463
self.tx_broadcaster.broadcast_transactions(&[&broadcast_tx]);
94499464

@@ -9453,30 +9468,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
94539468
});
94549469
}
94559470
}
9456-
msgs.shutdown_result
9457-
},
9458-
(Some(msgs), None) => {
9459-
if let Some(msg) = msgs.open_channel {
9460-
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
9461-
node_id,
9462-
msg,
9463-
});
9464-
}
9465-
if let Some(msg) = msgs.funding_created {
9466-
pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
9467-
node_id,
9468-
msg,
9469-
});
9470-
}
9471-
if let Some(msg) = msgs.accept_channel {
9472-
pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
9473-
node_id,
9474-
msg,
9475-
});
9476-
}
9477-
None
9471+
} else {
9472+
// We don't know how to handle a channel_ready or signed_closing_tx for a
9473+
// non-funded channel.
9474+
debug_assert!(msgs.channel_ready.is_none());
9475+
debug_assert!(msgs.signed_closing_tx.is_none());
94789476
}
9479-
(None, _) => None,
9477+
msgs.shutdown_result
9478+
} else {
9479+
None
94809480
}
94819481
};
94829482

@@ -11528,26 +11528,10 @@ where
1152811528
let peer_state = &mut *peer_state_lock;
1152911529
let pending_msg_events = &mut peer_state.pending_msg_events;
1153011530
peer_state.channel_by_id.retain(|_, chan| {
11531-
match chan.as_funded_mut() {
11532-
Some(funded_chan) => {
11533-
let logger = WithChannelContext::from(&self.logger, &funded_chan.context, None);
11534-
if funded_chan.remove_uncommitted_htlcs_and_mark_paused(&&logger).is_ok() {
11535-
// We only retain funded channels that are not shutdown.
11536-
return true;
11537-
}
11538-
},
11539-
// If we get disconnected and haven't yet committed to a funding
11540-
// transaction, we can replay the `open_channel` on reconnection, so don't
11541-
// bother dropping the channel here. However, if we already committed to
11542-
// the funding transaction we don't yet support replaying the funding
11543-
// handshake (and bailing if the peer rejects it), so we force-close in
11544-
// that case.
11545-
None => {
11546-
if chan.is_resumable() {
11547-
return true;
11548-
}
11549-
},
11550-
};
11531+
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
11532+
if chan.peer_disconnected_is_resumable(&&logger) {
11533+
return true;
11534+
}
1155111535
// Clean up for removal.
1155211536
let context = chan.context_mut();
1155311537
let mut close_res = context.force_shutdown(false, ClosureReason::DisconnectedPeer);
@@ -11691,30 +11675,25 @@ where
1169111675
let pending_msg_events = &mut peer_state.pending_msg_events;
1169211676

1169311677
for (_, chan) in peer_state.channel_by_id.iter_mut() {
11694-
match chan.as_funded_mut() {
11695-
Some(funded_chan) => {
11696-
let logger = WithChannelContext::from(&self.logger, &funded_chan.context, None);
11678+
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
11679+
match chan.peer_connected_get_handshake(self.chain_hash, &&logger) {
11680+
ReconnectionMsg::Reestablish(msg) =>
1169711681
pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
11698-
node_id: funded_chan.context.get_counterparty_node_id(),
11699-
msg: funded_chan.get_channel_reestablish(&&logger),
11700-
});
11701-
},
11702-
None => match chan.maybe_get_open_channel(self.chain_hash, &self.logger) {
11703-
Some(OpenChannelMessage::V1(msg)) => {
11704-
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
11705-
node_id: chan.context().get_counterparty_node_id(),
11706-
msg,
11707-
});
11708-
},
11709-
#[cfg(dual_funding)]
11710-
Some(OpenChannelMessage::V2(msg)) => {
11711-
pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 {
11712-
node_id: chan.context().get_counterparty_node_id(),
11713-
msg,
11714-
});
11715-
},
11716-
None => {},
11717-
},
11682+
node_id: chan.context().get_counterparty_node_id(),
11683+
msg,
11684+
}),
11685+
ReconnectionMsg::Open(OpenChannelMessage::V1(msg)) =>
11686+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
11687+
node_id: chan.context().get_counterparty_node_id(),
11688+
msg,
11689+
}),
11690+
#[cfg(dual_funding)]
11691+
ReconnectionMsg::Open(OpenChannelMessage::V2(msg)) =>
11692+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 {
11693+
node_id: chan.context().get_counterparty_node_id(),
11694+
msg,
11695+
}),
11696+
ReconnectionMsg::None => {},
1171811697
}
1171911698
}
1172011699
}

0 commit comments

Comments
 (0)