Skip to content

Commit 83d0b1c

Browse files
committed
f simplify disconnection logic a good bit with more utils
1 parent f6200f2 commit 83d0b1c

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

lightning/src/ln/channelmanager.rs

+41-37
Original file line numberDiff line numberDiff line change
@@ -4263,28 +4263,35 @@ where
42634263
Ok(())
42644264
}
42654265

4266+
fn unfunded_channel_count(
4267+
peer: &PeerState<<SP::Target as SignerProvider>::Signer>, best_block_height: u32
4268+
) -> usize {
4269+
let mut num_unfunded_channels = 0;
4270+
for (_, chan) in peer.channel_by_id.iter() {
4271+
if !chan.is_outbound() && chan.minimum_depth().unwrap_or(1) != 0 &&
4272+
chan.get_funding_tx_confirmations(best_block_height) == 0
4273+
{
4274+
num_unfunded_channels += 1;
4275+
}
4276+
}
4277+
num_unfunded_channels
4278+
}
4279+
42664280
/// Gets the number of peers which match the given filter which do not have any funded,
42674281
/// outbound, or 0-conf channels.
42684282
///
42694283
/// The filter is called for each peer and provided with the number of unfunded, inbound, and
42704284
/// non-0-conf channels we have with the peer.
42714285
fn peers_without_funded_channels<Filter>(&self, mut filter: Filter) -> usize
4272-
where Filter: FnMut(&PublicKey, &PeerState<<SP::Target as SignerProvider>::Signer>, usize) -> bool {
4286+
where Filter: FnMut(&PeerState<<SP::Target as SignerProvider>::Signer>) -> bool {
42734287
let mut peers_without_funded_channels = 0;
42744288
let best_block_height = self.best_block.read().unwrap().height();
42754289
{
42764290
let peer_state_lock = self.per_peer_state.read().unwrap();
4277-
for (node_id, peer_mtx) in peer_state_lock.iter() {
4291+
for (_, peer_mtx) in peer_state_lock.iter() {
42784292
let peer = peer_mtx.lock().unwrap();
4279-
let mut num_unfunded_channels = 0;
4280-
for (_, chan) in peer.channel_by_id.iter() {
4281-
if !chan.is_outbound() && chan.minimum_depth().unwrap_or(1) != 0 &&
4282-
chan.get_funding_tx_confirmations(best_block_height) == 0
4283-
{
4284-
num_unfunded_channels += 1;
4285-
}
4286-
}
4287-
if !filter(node_id, &*peer, num_unfunded_channels) { continue; }
4293+
if !filter(&*peer) { continue; }
4294+
let num_unfunded_channels = Self::unfunded_channel_count(&peer, best_block_height);
42884295
if num_unfunded_channels == peer.channel_by_id.len() {
42894296
peers_without_funded_channels += 1;
42904297
}
@@ -4316,21 +4323,16 @@ where
43164323
// Get the number of peers with channels, but without funded ones. We don't care too much
43174324
// about peers that never open a channel, so we filter by peers that have at least one
43184325
// channel, and then limit the number of those with unfunded channels.
4319-
let mut this_node_unfunded_channels = 0;
4320-
let peers_without_funded_channels = self.peers_without_funded_channels(
4321-
|node_id, node, unfunded_channels| {
4322-
if node_id == counterparty_node_id {
4323-
this_node_unfunded_channels = unfunded_channels;
4324-
}
4325-
!node.channel_by_id.is_empty()
4326-
});
4327-
if this_node_unfunded_channels >= MAX_UNFUNDED_CHANS_PER_PEER {
4326+
let peers_without_funded_channels = self.peers_without_funded_channels(|node| !node.channel_by_id.is_empty());
4327+
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
4328+
let peer_state = &mut *peer_state_lock;
4329+
4330+
let best_block_height = self.best_block.read().unwrap().height();
4331+
if Self::unfunded_channel_count(peer_state, best_block_height) >= MAX_UNFUNDED_CHANS_PER_PEER {
43284332
return Err(MsgHandleErrInternal::send_err_msg_no_close(
43294333
format!("Refusing more than {} unfunded channels.", MAX_UNFUNDED_CHANS_PER_PEER),
43304334
msg.temporary_channel_id.clone()));
43314335
}
4332-
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
4333-
let peer_state = &mut *peer_state_lock;
43344336
// If this peer already has some channels, a new channel won't increase our number of peers
43354337
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
43364338
// channels per-peer we can accept channels from a peer with existing ones.
@@ -4342,7 +4344,7 @@ where
43424344

43434345
let mut channel = match Channel::new_from_req(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
43444346
counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features, msg, user_channel_id,
4345-
&self.default_configuration, self.best_block.read().unwrap().height(), &self.logger, outbound_scid_alias)
4347+
&self.default_configuration, best_block_height, &self.logger, outbound_scid_alias)
43464348
{
43474349
Err(e) => {
43484350
self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
@@ -6296,25 +6298,19 @@ where
62966298
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
62976299

62986300
// If we have too many peers connected which don't have funded channels, disconnect the
6299-
// peer immediately. If we have a bunch of unfunded channels taking up space in memory for
6300-
// disconnected peers, we still let new peers connect, but we'll reject new channels from
6301-
// them.
6302-
let mut this_peer_has_funded_channels = false;
6303-
let connected_peers_without_funded_channels = self.peers_without_funded_channels(
6304-
|node_id, node, num_unfunded_channels| {
6305-
if node_id == counterparty_node_id && num_unfunded_channels != node.channel_by_id.len() {
6306-
this_peer_has_funded_channels = true;
6307-
}
6308-
node.is_connected
6309-
});
6310-
if inbound && !this_peer_has_funded_channels && connected_peers_without_funded_channels >= MAX_NO_CHANNEL_PEERS {
6311-
return Err(());
6312-
}
6301+
// peer immediately (as long as it doesn't have funded channels). If we have a bunch of
6302+
// unfunded channels taking up space in memory for disconnected peers, we still let new
6303+
// peers connect, but we'll reject new channels from them.
6304+
let connected_peers_without_funded_channels = self.peers_without_funded_channels(|node| node.is_connected);
6305+
let inbound_peer_limited = inbound && connected_peers_without_funded_channels >= MAX_NO_CHANNEL_PEERS;
63136306

63146307
{
63156308
let mut peer_state_lock = self.per_peer_state.write().unwrap();
63166309
match peer_state_lock.entry(counterparty_node_id.clone()) {
63176310
hash_map::Entry::Vacant(e) => {
6311+
if inbound_peer_limited {
6312+
return Err(());
6313+
}
63186314
e.insert(Mutex::new(PeerState {
63196315
channel_by_id: HashMap::new(),
63206316
latest_features: init_msg.features.clone(),
@@ -6325,6 +6321,14 @@ where
63256321
hash_map::Entry::Occupied(e) => {
63266322
let mut peer_state = e.get().lock().unwrap();
63276323
peer_state.latest_features = init_msg.features.clone();
6324+
6325+
let best_block_height = self.best_block.read().unwrap().height();
6326+
if Self::unfunded_channel_count(&*peer_state, best_block_height) ==
6327+
peer_state.channel_by_id.len() && inbound_peer_limited
6328+
{
6329+
return Err(());
6330+
}
6331+
63286332
debug_assert!(!peer_state.is_connected, "A peer shouldn't be connected twice");
63296333
peer_state.is_connected = true;
63306334
},

0 commit comments

Comments
 (0)