Skip to content

Commit

Permalink
LSPS2: Prune empty PeerStates
Browse files Browse the repository at this point in the history
In addition to pruning expired requests on peer disconnection we also
regularly prune for all peers on block connection, and also remove the
entire `PeerState` if it's empty after pruning (i.e., has no pending
requsts or in-flight channels left).
  • Loading branch information
tnull committed Dec 11, 2024
1 parent bdea03e commit 08fd499
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
32 changes: 27 additions & 5 deletions lightning-liquidity/src/lsps2/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ impl PeerState {
self.outbound_channels_by_intercept_scid.insert(intercept_scid, channel);
}

fn peer_disconnected(&mut self) {
fn prune_expired_request_state(&mut self) {
self.pending_requests.retain(|_, entry| {
match entry {
LSPS2Request::GetInfo(_) => false,
Expand All @@ -495,6 +495,11 @@ impl PeerState {
true
});
}

fn is_prunable(&self) -> bool {
// Return whether the entire state is empty.
self.pending_requests.is_empty() && self.outbound_channels_by_intercept_scid.is_empty()
}
}

/// The main object allowing to send and receive LSPS2 messages.
Expand Down Expand Up @@ -1270,12 +1275,29 @@ where
}

pub(crate) fn peer_disconnected(&self, counterparty_node_id: PublicKey) {
let outer_state_lock = self.per_peer_state.write().unwrap();
if let Some(inner_state_lock) = outer_state_lock.get(&counterparty_node_id) {
let mut peer_state_lock = inner_state_lock.lock().unwrap();
peer_state_lock.peer_disconnected();
let mut outer_state_lock = self.per_peer_state.write().unwrap();
let is_prunable =
if let Some(inner_state_lock) = outer_state_lock.get(&counterparty_node_id) {
let mut peer_state_lock = inner_state_lock.lock().unwrap();
peer_state_lock.prune_expired_request_state();
peer_state_lock.is_prunable()
} else {
return;
};
if is_prunable {
outer_state_lock.remove(&counterparty_node_id);
}
}

#[allow(clippy::bool_comparison)]
pub(crate) fn prune_peer_state(&self) {
let mut outer_state_lock = self.per_peer_state.write().unwrap();
outer_state_lock.retain(|_, inner_state_lock| {
let mut peer_state_lock = inner_state_lock.lock().unwrap();
peer_state_lock.prune_expired_request_state();
peer_state_lock.is_prunable() == false
});
}
}

impl<CM: Deref + Clone> ProtocolMessageHandler for LSPS2ServiceHandler<CM>
Expand Down
3 changes: 3 additions & 0 deletions lightning-liquidity/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,9 @@ where

fn best_block_updated(&self, _header: &bitcoin::block::Header, _height: u32) {
// TODO: Call best_block_updated on all sub-modules that require it, e.g., LSPS1MessageHandler.
if let Some(lsps2_service_handler) = self.lsps2_service_handler.as_ref() {
lsps2_service_handler.prune_peer_state();
}
}

fn get_relevant_txids(&self) -> Vec<(bitcoin::Txid, u32, Option<bitcoin::BlockHash>)> {
Expand Down

0 comments on commit 08fd499

Please sign in to comment.