Skip to content

Commit 2e24d5e

Browse files
authored
Merge pull request #396 from subspace/port-selection-improvements
Port selection improvements
2 parents a8952a0 + edb7010 commit 2e24d5e

File tree

2 files changed

+41
-6
lines changed
  • crates
    • subspace-farmer/src/bin/subspace-farmer/commands
    • subspace-networking/src

2 files changed

+41
-6
lines changed

crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use anyhow::{anyhow, Result};
22
use jsonrpsee::ws_server::WsServerBuilder;
3-
use log::info;
3+
use log::{info, warn};
44
use std::mem;
55
use std::sync::Arc;
66
use std::time::Duration;
@@ -24,7 +24,7 @@ pub(crate) async fn farm(
2424
custom_path,
2525
listen_on,
2626
node_rpc_url,
27-
ws_server_listen_addr,
27+
mut ws_server_listen_addr,
2828
reward_address,
2929
plot_size,
3030
}: FarmingArgs,
@@ -79,9 +79,25 @@ pub(crate) async fn farm(
7979
.await?;
8080

8181
// Start RPC server
82-
let ws_server = WsServerBuilder::default()
82+
let ws_server = match WsServerBuilder::default()
8383
.build(ws_server_listen_addr)
84-
.await?;
84+
.await
85+
{
86+
Ok(ws_server) => ws_server,
87+
Err(jsonrpsee::core::Error::Transport(error)) => {
88+
warn!(
89+
"Failed to start WebSocket RPC server on {ws_server_listen_addr} ({error}),\
90+
trying random port"
91+
);
92+
ws_server_listen_addr.set_port(0);
93+
WsServerBuilder::default()
94+
.build(ws_server_listen_addr)
95+
.await?
96+
}
97+
Err(error) => {
98+
return Err(error.into());
99+
}
100+
};
85101
let ws_server_addr = ws_server.local_addr()?;
86102
let rpc_server = RpcServerImpl::new(
87103
record_size,

crates/subspace-networking/src/create.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use libp2p::tcp::TokioTcpConfig;
1717
use libp2p::websocket::WsConfig;
1818
use libp2p::yamux::{WindowUpdateMode, YamuxConfig};
1919
use libp2p::{core, identity, noise, Multiaddr, PeerId, Transport, TransportError};
20+
use log::info;
2021
use std::sync::Arc;
2122
use std::time::Duration;
2223
use std::{fmt, io};
@@ -36,6 +37,8 @@ pub struct Config {
3637
pub bootstrap_nodes: Vec<Multiaddr>,
3738
/// List of [`Multiaddr`] on which to listen for incoming connections.
3839
pub listen_on: Vec<Multiaddr>,
40+
/// Fallback to random port if specified (or default) port is already occupied.
41+
pub listen_on_fallback_to_random_port: bool,
3942
/// Adds a timeout to the setup and protocol upgrade process for all inbound and outbound
4043
/// connections established through the transport.
4144
pub timeout: Duration,
@@ -98,6 +101,7 @@ impl Config {
98101
keypair,
99102
bootstrap_nodes: vec![],
100103
listen_on: vec![],
104+
listen_on_fallback_to_random_port: true,
101105
timeout: Duration::from_secs(10),
102106
identify,
103107
kademlia,
@@ -129,6 +133,7 @@ pub async fn create(
129133
Config {
130134
keypair,
131135
listen_on,
136+
listen_on_fallback_to_random_port,
132137
timeout,
133138
identify,
134139
kademlia,
@@ -198,8 +203,22 @@ pub async fn create(
198203
}))
199204
.build();
200205

201-
for addr in listen_on {
202-
swarm.listen_on(addr)?;
206+
for mut addr in listen_on {
207+
if let Err(error) = swarm.listen_on(addr.clone()) {
208+
if !listen_on_fallback_to_random_port {
209+
return Err(error.into());
210+
}
211+
212+
let addr_string = addr.to_string();
213+
// Listen on random port if specified is already occupied
214+
if let Some(Protocol::Tcp(_port)) = addr.pop() {
215+
info!(
216+
"Failed to listen on {addr_string} ({error}), falling back to random port"
217+
);
218+
addr.push(Protocol::Tcp(0));
219+
swarm.listen_on(addr)?;
220+
}
221+
}
203222
}
204223

205224
Ok::<_, CreationError>(swarm)

0 commit comments

Comments
 (0)