From af19055ba0e2a0352e4192b2290e25445746b707 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:07:46 +0200 Subject: [PATCH] notification: Fix memory leak of pending substreams (#296) This PR fixes a subtle memory leak that can happen in the following edge-case situation: - connection is established and substream outbound is initiated with remote peer - the substream ID is tracked until the substream either completes successfully or fails - the connection is closed soon after, leading to no substream events ever being generated For this edge-cases, we need to remove the tracking of the substream ID when the connection is reported as closed. This has been detected after running a node for more than 2 days with the following generic metrics PR: - https://github.com/paritytech/litep2p/pull/294 Closes: https://github.com/paritytech/litep2p/issues/295 cc @paritytech/networking --------- Signed-off-by: Alexandru Vasile --- src/protocol/notification/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/protocol/notification/mod.rs b/src/protocol/notification/mod.rs index 42063081..33108d3f 100644 --- a/src/protocol/notification/mod.rs +++ b/src/protocol/notification/mod.rs @@ -258,7 +258,7 @@ pub(crate) struct NotificationProtocol { /// Connected peers. peers: HashMap, - /// Pending outboudn substreams. + /// Pending outbound substreams. pending_outbound: HashMap, /// Handshaking service which reads and writes the handshakes to inbound @@ -384,6 +384,8 @@ impl NotificationProtocol { async fn on_connection_closed(&mut self, peer: PeerId) -> crate::Result<()> { tracing::trace!(target: LOG_TARGET, ?peer, protocol = %self.protocol, "connection closed"); + self.pending_outbound.retain(|_, p| p != &peer); + let Some(context) = self.peers.remove(&peer) else { tracing::error!( target: LOG_TARGET,