Skip to content

Commit 4b1e286

Browse files
committed
Create and use methods for counting channels
This commit also adds two new maps to `PeerState` for keeping track of `OutboundV1Channel`s and `InboundV1Channel`s so that further commits are a bit easier to review.
1 parent 4ad67cf commit 4b1e286

File tree

2 files changed

+79
-28
lines changed

2 files changed

+79
-28
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,18 @@ pub(super) struct PeerState<Signer: ChannelSigner> {
613613
/// `channel_id`, the `temporary_channel_id` key in the map is updated and is replaced by the
614614
/// `channel_id`.
615615
pub(super) channel_by_id: HashMap<[u8; 32], Channel<Signer>>,
616+
/// `temporary_channel_id` -> `OutboundV1Channel`.
617+
///
618+
/// Holds all outbound V1 channels where the peer is the counterparty. Once an outbound channel has
619+
/// been assigned a `channel_id`, the entry in this map is removed and one is created in
620+
/// `channel_by_id`.
621+
pub(super) outbound_v1_channel_by_id: HashMap<[u8; 32], OutboundV1Channel<Signer>>,
622+
/// `temporary_channel_id` -> `InboundV1Channel`.
623+
///
624+
/// Holds all inbound V1 channels where the peer is the counterparty. Once an inbound channel has
625+
/// been assigned a `channel_id`, the entry in this map is removed and one is created in
626+
/// `channel_by_id`.
627+
pub(super) inbound_v1_channel_by_id: HashMap<[u8; 32], InboundV1Channel<Signer>>,
616628
/// The latest `InitFeatures` we heard from the peer.
617629
latest_features: InitFeatures,
618630
/// Messages to send to the peer - pushed to in the same lock that they are generated in (except
@@ -654,6 +666,20 @@ impl <Signer: ChannelSigner> PeerState<Signer> {
654666
}
655667
self.channel_by_id.is_empty() && self.monitor_update_blocked_actions.is_empty()
656668
}
669+
670+
// Returns a count of all channels we have with this peer, including pending channels.
671+
fn total_channel_count(&self) -> usize {
672+
self.channel_by_id.len() +
673+
self.outbound_v1_channel_by_id.len() +
674+
self.inbound_v1_channel_by_id.len()
675+
}
676+
677+
// Returns a bool indicating if the given `channel_id` matches a channel we have with this peer.
678+
fn has_channel(&self, channel_id: &[u8; 32]) -> bool {
679+
self.channel_by_id.contains_key(channel_id) ||
680+
self.outbound_v1_channel_by_id.contains_key(channel_id) ||
681+
self.inbound_v1_channel_by_id.contains_key(channel_id)
682+
}
657683
}
658684

659685
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
@@ -4765,13 +4791,14 @@ where
47654791
fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> {
47664792
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
47674793

4768-
let peers_without_funded_channels = self.peers_without_funded_channels(|peer| !peer.channel_by_id.is_empty());
4794+
let peers_without_funded_channels =
4795+
self.peers_without_funded_channels(|peer| { peer.total_channel_count() > 0 });
47694796
let per_peer_state = self.per_peer_state.read().unwrap();
47704797
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
47714798
.ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
47724799
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
47734800
let peer_state = &mut *peer_state_lock;
4774-
let is_only_peer_channel = peer_state.channel_by_id.len() == 1;
4801+
let is_only_peer_channel = peer_state.total_channel_count() == 1;
47754802
match peer_state.channel_by_id.entry(temporary_channel_id.clone()) {
47764803
hash_map::Entry::Occupied(mut channel) => {
47774804
if !channel.get().inbound_is_awaiting_accept() {
@@ -4833,7 +4860,7 @@ where
48334860
let peer = peer_mtx.lock().unwrap();
48344861
if !maybe_count_peer(&*peer) { continue; }
48354862
let num_unfunded_channels = Self::unfunded_channel_count(&peer, best_block_height);
4836-
if num_unfunded_channels == peer.channel_by_id.len() {
4863+
if num_unfunded_channels == peer.total_channel_count() {
48374864
peers_without_funded_channels += 1;
48384865
}
48394866
}
@@ -4912,33 +4939,31 @@ where
49124939
},
49134940
Ok(res) => res
49144941
};
4915-
match peer_state.channel_by_id.entry(channel.context.channel_id()) {
4916-
hash_map::Entry::Occupied(_) => {
4917-
self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
4918-
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()))
4919-
},
4920-
hash_map::Entry::Vacant(entry) => {
4921-
if !self.default_configuration.manually_accept_inbound_channels {
4922-
if channel.context.get_channel_type().requires_zero_conf() {
4923-
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
4924-
}
4925-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
4926-
node_id: counterparty_node_id.clone(),
4927-
msg: channel.accept_inbound_channel(user_channel_id),
4928-
});
4929-
} else {
4930-
let mut pending_events = self.pending_events.lock().unwrap();
4931-
pending_events.push_back((events::Event::OpenChannelRequest {
4932-
temporary_channel_id: msg.temporary_channel_id.clone(),
4933-
counterparty_node_id: counterparty_node_id.clone(),
4934-
funding_satoshis: msg.funding_satoshis,
4935-
push_msat: msg.push_msat,
4936-
channel_type: channel.context.get_channel_type().clone(),
4937-
}, None));
4942+
let channel_id = channel.context.channel_id();
4943+
let channel_exists = peer_state.has_channel(&channel_id);
4944+
if channel_exists {
4945+
self.outbound_scid_aliases.lock().unwrap().remove(&outbound_scid_alias);
4946+
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()))
4947+
} else {
4948+
if !self.default_configuration.manually_accept_inbound_channels {
4949+
if channel.context.get_channel_type().requires_zero_conf() {
4950+
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
49384951
}
4939-
4940-
entry.insert(channel);
4952+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
4953+
node_id: counterparty_node_id.clone(),
4954+
msg: channel.accept_inbound_channel(user_channel_id),
4955+
});
4956+
} else {
4957+
let mut pending_events = self.pending_events.lock().unwrap();
4958+
pending_events.push_back((events::Event::OpenChannelRequest {
4959+
temporary_channel_id: msg.temporary_channel_id.clone(),
4960+
counterparty_node_id: counterparty_node_id.clone(),
4961+
funding_satoshis: msg.funding_satoshis,
4962+
push_msat: msg.push_msat,
4963+
channel_type: channel.context.get_channel_type().clone(),
4964+
}, None));
49414965
}
4966+
peer_state.channel_by_id.insert(channel_id, channel);
49424967
}
49434968
Ok(())
49444969
}
@@ -6878,6 +6903,8 @@ where
68786903
}
68796904
e.insert(Mutex::new(PeerState {
68806905
channel_by_id: HashMap::new(),
6906+
outbound_v1_channel_by_id: HashMap::new(),
6907+
inbound_v1_channel_by_id: HashMap::new(),
68816908
latest_features: init_msg.features.clone(),
68826909
pending_msg_events: Vec::new(),
68836910
monitor_update_blocked_actions: BTreeMap::new(),
@@ -8081,6 +8108,8 @@ where
80818108
let peer_pubkey = Readable::read(reader)?;
80828109
let peer_state = PeerState {
80838110
channel_by_id: peer_channels.remove(&peer_pubkey).unwrap_or(HashMap::new()),
8111+
outbound_v1_channel_by_id: HashMap::new(),
8112+
inbound_v1_channel_by_id: HashMap::new(),
80848113
latest_features: Readable::read(reader)?,
80858114
pending_msg_events: Vec::new(),
80868115
monitor_update_blocked_actions: BTreeMap::new(),

lightning/src/ln/functional_test_utils.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,28 @@ macro_rules! get_channel_ref {
783783
}
784784
}
785785

786+
#[cfg(test)]
787+
macro_rules! get_inbound_v1_channel_ref {
788+
($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => {
789+
{
790+
$per_peer_state_lock = $node.node.per_peer_state.read().unwrap();
791+
$peer_state_lock = $per_peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
792+
$peer_state_lock.inbound_v1_channel_by_id.get_mut(&$channel_id).unwrap()
793+
}
794+
}
795+
}
796+
797+
#[cfg(test)]
798+
macro_rules! get_outbound_v1_channel_ref {
799+
($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => {
800+
{
801+
$per_peer_state_lock = $node.node.per_peer_state.read().unwrap();
802+
$peer_state_lock = $per_peer_state_lock.get(&$counterparty_node.node.get_our_node_id()).unwrap().lock().unwrap();
803+
$peer_state_lock.outbound_v1_channel_by_id.get_mut(&$channel_id).unwrap()
804+
}
805+
}
806+
}
807+
786808
#[cfg(test)]
787809
macro_rules! get_feerate {
788810
($node: expr, $counterparty_node: expr, $channel_id: expr) => {

0 commit comments

Comments
 (0)