From e378e76bf1ee96373de4d7b342f5445ab75cc0be Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:51:11 +0300 Subject: [PATCH] transport: Fix pending dials memory leak (#271) The `pending_dials` is populated with a connection ID when initiating outbound connections. The state is rightfully cleaned up when the dialing fails, and error propagated back to the user. However, the state was not cleared when the dialing succeeded. This was leading to a subtle memory leak in litep2p. ### Testing Done I used a custom-patched version of litep2p to log the number of pending dials. After a few hours, the pending dials for both TCP and WebSocket connections stabilized at just a few. ``` 2024-10-22 17:37:56.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=1 pending_inbound_connections=0 pending_connections=1 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 2024-10-22 17:38:26.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=1 opened_raw=0 cancel_futures=1 pending_open=0 2024-10-22 17:38:56.253 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 2024-10-22 17:39:26.253 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 2024-10-22 17:39:56.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 2024-10-22 17:40:26.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=1 opened_raw=0 cancel_futures=1 pending_open=0 2024-10-22 17:40:56.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 2024-10-22 17:41:26.252 INFO tokio-runtime-worker litep2p::tcp: status pending_dials=0 pending_inbound_connections=0 pending_connections=0 pending_raw_connections=0 opened_raw=0 cancel_futures=0 pending_open=0 ``` Closes: https://github.com/paritytech/litep2p/issues/269 Signed-off-by: Alexandru Vasile --- src/transport/tcp/mod.rs | 1 + src/transport/websocket/mod.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/transport/tcp/mod.rs b/src/transport/tcp/mod.rs index 856c9410..24e4ef54 100644 --- a/src/transport/tcp/mod.rs +++ b/src/transport/tcp/mod.rs @@ -557,6 +557,7 @@ impl Stream for TcpTransport { Ok(connection) => { let peer = connection.peer(); let endpoint = connection.endpoint(); + self.pending_dials.remove(&connection.connection_id()); self.pending_open.insert(connection.connection_id(), connection); return Poll::Ready(Some(TransportEvent::ConnectionEstablished { diff --git a/src/transport/websocket/mod.rs b/src/transport/websocket/mod.rs index f7999735..03c58191 100644 --- a/src/transport/websocket/mod.rs +++ b/src/transport/websocket/mod.rs @@ -599,6 +599,7 @@ impl Stream for WebSocketTransport { Ok(connection) => { let peer = connection.peer(); let endpoint = connection.endpoint(); + self.pending_dials.remove(&connection.connection_id()); self.pending_open.insert(connection.connection_id(), connection); return Poll::Ready(Some(TransportEvent::ConnectionEstablished {