Skip to content

Commit 929deda

Browse files
committed
Don't fail channel creation when peer suddenly disconnects
- Instead broadcast the SendOpenChannel event again when the peer reconnects - Or fail the channel creation in some time, if channel does not reestablish.
1 parent 870a0f1 commit 929deda

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

lightning/src/ln/channelmanager.rs

+57-4
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,9 @@ pub(super) struct PeerState<SP: Deref> where SP::Target: SignerProvider {
742742
/// removed, and an InboundV1Channel is created and placed in the `inbound_v1_channel_by_id` table. If
743743
/// the channel is rejected, then the entry is simply removed.
744744
pub(super) inbound_channel_request_by_id: HashMap<ChannelId, InboundChannelRequest>,
745+
///
746+
/// Channels that were created but not notified about by sending SendOpenChannel Message
747+
pub(super) unnotified_outbound_channel: HashMap<ChannelId, OutboundChannelTimer>,
745748
/// The latest `InitFeatures` we heard from the peer.
746749
latest_features: InitFeatures,
747750
/// Messages to send to the peer - pushed to in the same lock that they are generated in (except
@@ -818,6 +821,15 @@ pub(super) struct InboundChannelRequest {
818821
/// accepted. An unaccepted channel that exceeds this limit will be abandoned.
819822
const UNACCEPTED_INBOUND_CHANNEL_AGE_LIMIT_TICKS: i32 = 2;
820823

824+
/// A timer to retain outbound channels that haven't been notified of their creation yet.
825+
pub(super) struct OutboundChannelTimer {
826+
pub ticks_remaining: i32,
827+
}
828+
829+
/// The maximum number of ticks allowed for waiting to notify an unnotified outbound channel.
830+
/// If an unnotified channel exceeds this limit, it will be abandoned.
831+
const UNSENT_OUTBOUND_CHANNEL_AGE_LIMIT_TICKS: i32 = 2;
832+
821833
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
822834
/// actually ours and not some duplicate HTLC sent to us by a node along the route.
823835
///
@@ -2475,10 +2487,19 @@ where
24752487
hash_map::Entry::Vacant(entry) => { entry.insert(ChannelPhase::UnfundedOutboundV1(channel)); }
24762488
}
24772489

2478-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
2479-
node_id: their_network_key,
2480-
msg: res,
2481-
});
2490+
if peer_state.is_connected {
2491+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
2492+
node_id: their_network_key,
2493+
msg: res
2494+
});
2495+
}
2496+
2497+
else {
2498+
peer_state.unnotified_outbound_channel.insert(temporary_channel_id, OutboundChannelTimer {
2499+
ticks_remaining: UNSENT_OUTBOUND_CHANNEL_AGE_LIMIT_TICKS,
2500+
});
2501+
}
2502+
24822503
Ok(temporary_channel_id)
24832504
}
24842505

@@ -4831,6 +4852,14 @@ where
48314852
}
48324853
peer_state.inbound_channel_request_by_id.retain(|_, req| req.ticks_remaining > 0);
48334854

4855+
// Force close the unnotified outbound channel, for which SendOpenChannel was not sent in timely manner.
4856+
for (chan_id, timer) in peer_state.unnotified_outbound_channel.iter_mut() {
4857+
if { timer.ticks_remaining -= 1 ; timer.ticks_remaining } <= 0 {
4858+
let _ = self.force_close_sending_error(&chan_id, &counterparty_node_id, true);
4859+
}
4860+
}
4861+
peer_state.unnotified_outbound_channel.retain(|_, timer| timer.ticks_remaining > 0);
4862+
48344863
if peer_state.ok_to_remove(true) {
48354864
pending_peers_awaiting_removal.push(counterparty_node_id);
48364865
}
@@ -8950,6 +8979,7 @@ where
89508979
e.insert(Mutex::new(PeerState {
89518980
channel_by_id: HashMap::new(),
89528981
inbound_channel_request_by_id: HashMap::new(),
8982+
unnotified_outbound_channel: HashMap::new(),
89538983
latest_features: init_msg.features.clone(),
89548984
pending_msg_events: Vec::new(),
89558985
in_flight_monitor_updates: BTreeMap::new(),
@@ -8985,11 +9015,33 @@ where
89859015
let peer_state = &mut *peer_state_lock;
89869016
let pending_msg_events = &mut peer_state.pending_msg_events;
89879017

9018+
// Notify channels that were left unnotified of their creation because
9019+
// the peer disconnected at that time, even though the channels were open.
9020+
for (chan_id, _) in peer_state.unnotified_outbound_channel.iter_mut() {
9021+
let channel = peer_state.channel_by_id.get(chan_id).and_then(|channel_phase| {
9022+
if let ChannelPhase::UnfundedOutboundV1(channel) = channel_phase {
9023+
Some(channel)
9024+
} else {
9025+
None
9026+
}
9027+
}).unwrap();
9028+
9029+
let res = channel.get_open_channel(self.chain_hash);
9030+
9031+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
9032+
node_id: *counterparty_node_id,
9033+
msg: res,
9034+
});
9035+
}
9036+
9037+
peer_state.unnotified_outbound_channel.clear();
9038+
89889039
peer_state.channel_by_id.iter_mut().filter_map(|(_, phase)|
89899040
if let ChannelPhase::Funded(chan) = phase { Some(chan) } else {
89909041
// Since unfunded channel maps are cleared upon disconnecting a peer, and they're not persisted
89919042
// (so won't be recovered after a crash), they shouldn't exist here and we would never need to
89929043
// worry about closing and removing them.
9044+
89939045
debug_assert!(false);
89949046
None
89959047
}
@@ -10346,6 +10398,7 @@ where
1034610398
PeerState {
1034710399
channel_by_id,
1034810400
inbound_channel_request_by_id: HashMap::new(),
10401+
unnotified_outbound_channel: HashMap::new(),
1034910402
latest_features: InitFeatures::empty(),
1035010403
pending_msg_events: Vec::new(),
1035110404
in_flight_monitor_updates: BTreeMap::new(),

0 commit comments

Comments
 (0)