Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli argument --rpc-allow-fallback-to-random-port #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/node/cli/benches/block_production.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
rpc_max_response_size: None,
rpc_id_provider: None,
rpc_max_subs_per_conn: None,
rpc_allow_fallback_to_random_port: true,
ws_max_out_buffer_capacity: None,
prometheus_config: None,
telemetry_endpoints: None,
Expand Down
1 change: 1 addition & 0 deletions bin/node/cli/benches/transaction_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
rpc_max_response_size: None,
rpc_id_provider: None,
rpc_max_subs_per_conn: None,
rpc_allow_fallback_to_random_port: true,
ws_max_out_buffer_capacity: None,
prometheus_config: None,
telemetry_endpoints: None,
Expand Down
9 changes: 9 additions & 0 deletions client/cli/src/commands/run_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ pub struct RunCmd {
#[arg(long)]
pub rpc_max_subscriptions_per_connection: Option<usize>,

/// Use random port if port configured for Websocket or HTTP is already in use
/// Default is true.
#[clap(long)]
pub rpc_allow_fallback_to_random_port: Option<bool>,

/// Expose Prometheus exporter on all interfaces.
///
/// Default is local.
Expand Down Expand Up @@ -465,6 +470,10 @@ impl CliConfiguration for RunCmd {
Ok(self.rpc_max_subscriptions_per_connection)
}

fn rpc_allow_fallback_to_random_port(&self) -> Result<bool> {
Ok(self.rpc_allow_fallback_to_random_port.unwrap_or(true))
}

fn ws_max_out_buffer_capacity(&self) -> Result<Option<usize>> {
Ok(self.ws_max_out_buffer_capacity)
}
Expand Down
6 changes: 6 additions & 0 deletions client/cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
Ok(None)
}

/// Use random port if port configured for Websocket or HTTP is already in use
fn rpc_allow_fallback_to_random_port(&self) -> Result<bool> {
Ok(true)
}

/// Get maximum WS output buffer capacity.
fn ws_max_out_buffer_capacity(&self) -> Result<Option<usize>> {
Ok(None)
Expand Down Expand Up @@ -544,6 +549,7 @@ pub trait CliConfiguration<DCV: DefaultConfigurationValues = ()>: Sized {
rpc_max_response_size: self.rpc_max_response_size()?,
rpc_id_provider: None,
rpc_max_subs_per_conn: self.rpc_max_subscriptions_per_connection()?,
rpc_allow_fallback_to_random_port: self.rpc_allow_fallback_to_random_port()?,
ws_max_out_buffer_capacity: self.ws_max_out_buffer_capacity()?,
prometheus_config: self
.prometheus_config(DCV::prometheus_listen_port(), &chain_spec)?,
Expand Down
84 changes: 52 additions & 32 deletions client/rpc-servers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl WsConfig {

/// Start HTTP server listening on given address.
pub async fn start_http<M: Send + Sync + 'static>(
addrs: [SocketAddr; 2],
addrs: &[SocketAddr],
cors: Option<&Vec<String>>,
max_payload_in_mb: Option<usize>,
max_payload_out_mb: Option<usize>,
Expand All @@ -95,7 +95,7 @@ pub async fn start_http<M: Send + Sync + 'static>(
if let Some(cors) = cors {
// Whitelist listening address.
// NOTE: set_allowed_hosts will whitelist both ports but only one will used.
acl = acl.set_allowed_hosts(format_allowed_hosts(&addrs[..]))?;
acl = acl.set_allowed_hosts(format_allowed_hosts(addrs))?;
acl = acl.set_allowed_origins(cors)?;
};

Expand All @@ -107,30 +107,40 @@ pub async fn start_http<M: Send + Sync + 'static>(
.custom_tokio_runtime(rt);

let rpc_api = build_rpc_api(rpc_api);
let (handle, addr) = if let Some(metrics) = metrics {
let server_start_result = if let Some(metrics) = metrics {
let middleware = RpcMiddleware::new(metrics, "http".into());
let builder = builder.set_middleware(middleware);
let server = builder.build(&addrs[..]).await?;
let addr = server.local_addr();
(server.start(rpc_api)?, addr)
builder.build(addrs).await.and_then(|server| {
let addr = server.local_addr();
Ok((server.start(rpc_api)?, addr))
})
} else {
let server = builder.build(&addrs[..]).await?;
let addr = server.local_addr();
(server.start(rpc_api)?, addr)
builder.build(addrs).await.and_then(|server| {
let addr = server.local_addr();
Ok((server.start(rpc_api)?, addr))
})
};

log::info!(
"Running JSON-RPC HTTP server: addr={}, allowed origins={:?}",
addr.map_or_else(|_| "unknown".to_string(), |a| a.to_string()),
cors
);

Ok(handle)
match server_start_result {
Ok((handle, addr)) => {
log::info!(
"Running JSON-RPC HTTP server: addr={}, allowed origins={:?}",
addr.map_or_else(|_| "unknown".to_string(), |a| a.to_string()),
cors
);

Ok(handle)
},
Err(error) => {
log::info!("Error on starting JSON-RPC HTTP server: {}", error);
Err(error.into())
},
}
}

/// Start WS server listening on given address.
pub async fn start_ws<M: Send + Sync + 'static>(
addrs: [SocketAddr; 2],
addrs: &[SocketAddr],
cors: Option<&Vec<String>>,
ws_config: WsConfig,
metrics: Option<RpcMetrics>,
Expand All @@ -146,7 +156,7 @@ pub async fn start_ws<M: Send + Sync + 'static>(
if let Some(cors) = cors {
// Whitelist listening address.
// NOTE: set_allowed_hosts will whitelist both ports but only one will used.
acl = acl.set_allowed_hosts(format_allowed_hosts(&addrs[..]))?;
acl = acl.set_allowed_hosts(format_allowed_hosts(addrs))?;
acl = acl.set_allowed_origins(cors)?;
};

Expand All @@ -166,25 +176,35 @@ pub async fn start_ws<M: Send + Sync + 'static>(
};

let rpc_api = build_rpc_api(rpc_api);
let (handle, addr) = if let Some(metrics) = metrics {
let server_start_result = if let Some(metrics) = metrics {
let middleware = RpcMiddleware::new(metrics, "ws".into());
let builder = builder.set_middleware(middleware);
let server = builder.build(&addrs[..]).await?;
let addr = server.local_addr();
(server.start(rpc_api)?, addr)
builder.build(addrs).await.and_then(|server| {
let addr = server.local_addr();
Ok((server.start(rpc_api)?, addr))
})
} else {
let server = builder.build(&addrs[..]).await?;
let addr = server.local_addr();
(server.start(rpc_api)?, addr)
builder.build(addrs).await.and_then(|server| {
let addr = server.local_addr();
Ok((server.start(rpc_api)?, addr))
})
};

log::info!(
"Running JSON-RPC WS server: addr={}, allowed origins={:?}",
addr.map_or_else(|_| "unknown".to_string(), |a| a.to_string()),
cors
);

Ok(handle)
match server_start_result {
Ok((handle, addr)) => {
log::info!(
"Running JSON-RPC WS server: addr={}, allowed origins={:?}",
addr.map_or_else(|_| "unknown".to_string(), |a| a.to_string()),
cors
);

Ok(handle)
},
Err(error) => {
log::info!("Error on starting JSON-RPC WS server: {}", error);
Err(error.into())
},
}
}

fn format_allowed_hosts(addrs: &[SocketAddr]) -> Vec<String> {
Expand Down
2 changes: 2 additions & 0 deletions client/service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ pub struct Configuration {
///
/// Default: 1024.
pub rpc_max_subs_per_conn: Option<usize>,
/// Use random port if port configured for Websocket or HTTP is already in use
pub rpc_allow_fallback_to_random_port: bool,
/// Maximum size of the output buffer capacity for websocket connections.
pub ws_max_out_buffer_capacity: Option<usize>,
/// Prometheus endpoint configuration. `None` if disabled.
Expand Down
14 changes: 9 additions & 5 deletions client/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,20 @@ where
let ws_addr = config
.rpc_ws
.unwrap_or_else(|| "127.0.0.1:9944".parse().expect("valid sockaddr; qed"));
let ws_addr2 = random_port(ws_addr);
let ws_addrs = [ws_addr, random_port(ws_addr)];
let ws_addrs =
if config.rpc_allow_fallback_to_random_port { &ws_addrs[..] } else { &ws_addrs[..1] };

let http_addr = config
.rpc_http
.unwrap_or_else(|| "127.0.0.1:9933".parse().expect("valid sockaddr; qed"));
let http_addr2 = random_port(http_addr);
let http_addrs = [http_addr, random_port(http_addr)];
let http_addrs =
if config.rpc_allow_fallback_to_random_port { &http_addrs[..] } else { &http_addrs[..1] };

let metrics = sc_rpc_server::RpcMetrics::new(config.prometheus_registry())?;

let http_fut = sc_rpc_server::start_http(
[http_addr, http_addr2],
http_addrs,
config.rpc_cors.as_ref(),
max_request_size,
http_max_response_size,
Expand All @@ -371,7 +375,7 @@ where
};

let ws_fut = sc_rpc_server::start_ws(
[ws_addr, ws_addr2],
ws_addrs,
config.rpc_cors.as_ref(),
ws_config,
metrics,
Expand Down
1 change: 1 addition & 0 deletions client/service/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ fn node_config<
rpc_max_response_size: None,
rpc_id_provider: None,
rpc_max_subs_per_conn: None,
rpc_allow_fallback_to_random_port: true,
ws_max_out_buffer_capacity: None,
prometheus_config: None,
telemetry_endpoints: None,
Expand Down