P2P: Add hourly warning logging for no incoming P2P connections (#520)

* Add hourly logging for no incoming P2P connections

* Address clippy findings

* Avoid creating Duration inside monitoring loop

---------

Co-authored-by: Omar Murad <me@omar-murad.com>
This commit is contained in:
Omar
2025-08-07 09:28:33 -04:00
committed by GitHub
parent 9c2c942d2f
commit 00e4a498b3
2 changed files with 57 additions and 3 deletions

View File

@@ -40,6 +40,7 @@ pub(super) async fn inbound_server<Z, T, HS, A>(
mut address_book: A,
config: P2PConfig<Z>,
transport_config: Option<T::ServerConfig>,
inbound_semaphore: Arc<Semaphore>,
) -> Result<(), tower::BoxError>
where
Z: NetworkZone,
@@ -67,8 +68,8 @@ where
let mut listener = pin!(listener);
// Create semaphore for limiting to maximum inbound connections.
let semaphore = Arc::new(Semaphore::new(config.max_inbound_connections));
// Use the provided semaphore for limiting to maximum inbound connections.
let semaphore = inbound_semaphore;
// Create ping request handling JoinSet
let mut ping_join_set = JoinSet::new();

View File

@@ -5,7 +5,11 @@
use std::sync::Arc;
use futures::FutureExt;
use tokio::{sync::mpsc, task::JoinSet};
use tokio::{
sync::mpsc,
task::JoinSet,
time::{sleep, Duration},
};
use tower::{buffer::Buffer, util::BoxCloneService, Service, ServiceExt};
use tracing::{instrument, Instrument, Span};
@@ -31,6 +35,40 @@ use connection_maintainer::MakeConnectionRequest;
use peer_set::PeerSet;
pub use peer_set::{ClientDropGuard, PeerSetRequest, PeerSetResponse};
/// Interval for checking inbound connection status (1 hour)
const INBOUND_CONNECTION_MONITOR_INTERVAL: Duration = Duration::from_secs(3600);
/// Monitors for inbound connections and logs a warning if none are detected.
///
/// This task runs every hour to check if there are inbound connections available.
/// If `max_inbound_connections` is 0, the task will exit without logging.
#[expect(clippy::infinite_loop)]
async fn inbound_connection_monitor(
inbound_semaphore: Arc<tokio::sync::Semaphore>,
max_inbound_connections: usize,
p2p_port: u16,
) {
// Skip monitoring if inbound connections are disabled
if max_inbound_connections == 0 {
return;
}
loop {
// Wait for the monitoring interval
sleep(INBOUND_CONNECTION_MONITOR_INTERVAL).await;
// Check if we have any inbound connections
// If available permits equals max_inbound_connections, no peers are connected
let available_permits = inbound_semaphore.available_permits();
if available_permits == max_inbound_connections {
tracing::warn!(
"No incoming connections - check firewalls/routers allow port {}",
p2p_port
);
}
}
}
/// Initializes the P2P [`NetworkInterface`] for a specific [`NetworkZone`].
///
/// This function starts all the tasks to maintain/accept/make connections.
@@ -111,6 +149,9 @@ where
let peer_set = PeerSet::new(new_connection_rx);
// Create semaphore for limiting inbound connections and monitoring
let inbound_semaphore = Arc::new(tokio::sync::Semaphore::new(config.max_inbound_connections));
let mut background_tasks = JoinSet::new();
background_tasks.spawn(
@@ -118,6 +159,17 @@ where
.run()
.instrument(Span::current()),
);
// Spawn inbound connection monitor task
background_tasks.spawn(
inbound_connection_monitor(
Arc::clone(&inbound_semaphore),
config.max_inbound_connections,
config.p2p_port,
)
.instrument(tracing::info_span!("inbound_connection_monitor")),
);
background_tasks.spawn(
inbound_server::inbound_server(
new_connection_tx,
@@ -125,6 +177,7 @@ where
address_book.clone(),
config,
transport_config.server_config,
inbound_semaphore,
)
.map(|res| {
if let Err(e) = res {