diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 508f082d8c37f..cc950865ce07e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ variables: NEXTEST_FAILURE_OUTPUT: immediate-final NEXTEST_SUCCESS_OUTPUT: final - ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.43" + ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.48" default: retry: diff --git a/bin/node/cli/benches/block_production.rs b/bin/node/cli/benches/block_production.rs index c7f0cd20efd5b..36e8076925ebc 100644 --- a/bin/node/cli/benches/block_production.rs +++ b/bin/node/cli/benches/block_production.rs @@ -84,18 +84,14 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { offchain_worker: execution_strategy, other: execution_strategy, }, - rpc_http: None, - rpc_ws: None, - rpc_ipc: None, - rpc_ws_max_connections: None, + rpc_addr: None, + rpc_max_connections: Default::default(), rpc_cors: None, rpc_methods: Default::default(), - rpc_max_payload: None, - rpc_max_request_size: None, - rpc_max_response_size: None, - rpc_id_provider: None, - rpc_max_subs_per_conn: None, - ws_max_out_buffer_capacity: None, + rpc_max_request_size: Default::default(), + rpc_max_response_size: Default::default(), + rpc_id_provider: Default::default(), + rpc_max_subs_per_conn: Default::default(), prometheus_config: None, telemetry_endpoints: None, default_heap_pages: None, diff --git a/bin/node/cli/benches/transaction_pool.rs b/bin/node/cli/benches/transaction_pool.rs index abee9c846245f..14d99c37a4a33 100644 --- a/bin/node/cli/benches/transaction_pool.rs +++ b/bin/node/cli/benches/transaction_pool.rs @@ -78,18 +78,14 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { offchain_worker: sc_client_api::ExecutionStrategy::NativeWhenPossible, other: sc_client_api::ExecutionStrategy::NativeWhenPossible, }, - rpc_http: None, - rpc_ws: None, - rpc_ipc: None, - rpc_ws_max_connections: None, + rpc_addr: None, + rpc_max_connections: Default::default(), rpc_cors: None, rpc_methods: Default::default(), - rpc_max_payload: None, - rpc_max_request_size: None, - rpc_max_response_size: None, - rpc_id_provider: None, - rpc_max_subs_per_conn: None, - ws_max_out_buffer_capacity: None, + rpc_max_request_size: Default::default(), + rpc_max_response_size: Default::default(), + rpc_id_provider: Default::default(), + rpc_max_subs_per_conn: Default::default(), prometheus_config: None, telemetry_endpoints: None, default_heap_pages: None, diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs index 7cc1e6c730cc9..8176643d73cd2 100644 --- a/client/cli/src/commands/run_cmd.rs +++ b/client/cli/src/commands/run_cmd.rs @@ -65,7 +65,7 @@ pub struct RunCmd { /// RPC methods to expose. /// - `unsafe`: Exposes every RPC method. /// - `safe`: Exposes only a safe subset of RPC methods, denying unsafe RPC methods. - /// - `auto`: Acts as `safe` if RPC is served externally, e.g. when `--{rpc,ws}-external` is + /// - `auto`: Acts as `safe` if RPC is served externally, e.g. when `--rpc--external` is /// passed, otherwise acts as `unsafe`. #[arg( long, @@ -77,58 +77,25 @@ pub struct RunCmd { )] pub rpc_methods: RpcMethods, - /// Listen to all Websocket interfaces. - /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC - /// proxy server to filter out dangerous methods. More details: - /// . - /// Use `--unsafe-ws-external` to suppress the warning if you understand the risks. - #[arg(long)] - pub ws_external: bool, - - /// Listen to all Websocket interfaces. - /// Same as `--ws-external` but doesn't warn you about it. - #[arg(long)] - pub unsafe_ws_external: bool, - - /// DEPRECATED, this has no affect anymore. Use `rpc_max_request_size` or - /// `rpc_max_response_size` instead. - #[arg(long)] - pub rpc_max_payload: Option, - /// Set the the maximum RPC request payload size for both HTTP and WS in megabytes. - /// Default is 15MiB. - #[arg(long)] - pub rpc_max_request_size: Option, + #[arg(long, default_value_t = 15)] + pub rpc_max_request_size: u32, /// Set the the maximum RPC response payload size for both HTTP and WS in megabytes. - /// Default is 15MiB. - #[arg(long)] - pub rpc_max_response_size: Option, + #[arg(long, default_value_t = 15)] + pub rpc_max_response_size: u32, /// Set the the maximum concurrent subscriptions per connection. - /// Default is 1024. - #[arg(long)] - pub rpc_max_subscriptions_per_connection: Option, + #[arg(long, default_value_t = 1024)] + pub rpc_max_subscriptions_per_connection: u32, - /// DEPRECATED, IPC support has been removed. - #[arg(long, value_name = "PATH")] - pub ipc_path: Option, + /// Specify JSON-RPC server TCP port. + #[arg(long, value_name = "PORT", default_value_t = 9944)] + pub rpc_port: u16, - /// Specify HTTP RPC server TCP port. - #[arg(long, value_name = "PORT")] - pub rpc_port: Option, - - /// Specify WebSockets RPC server TCP port. - #[arg(long, value_name = "PORT")] - pub ws_port: Option, - - /// Maximum number of WS RPC server connections. - #[arg(long, value_name = "COUNT")] - pub ws_max_connections: Option, - - /// DEPRECATED, this has no affect anymore. Use `rpc_max_response_size` instead. - #[arg(long)] - pub ws_max_out_buffer_capacity: Option, + /// Maximum number of RPC server connections. + #[arg(long, value_name = "COUNT", default_value_t = 100)] + pub rpc_max_connections: u32, /// Specify browser Origins allowed to access the HTTP & WS RPC servers. /// A comma-separated list of origins (protocol://domain or special `null` @@ -344,8 +311,8 @@ impl CliConfiguration for RunCmd { Ok(self.no_grandpa) } - fn rpc_ws_max_connections(&self) -> Result> { - Ok(self.ws_max_connections) + fn rpc_max_connections(&self) -> Result { + Ok(self.rpc_max_connections) } fn rpc_cors(&self, is_dev: bool) -> Result>> { @@ -369,7 +336,7 @@ impl CliConfiguration for RunCmd { .into()) } - fn rpc_http(&self, default_listen_port: u16) -> Result> { + fn rpc_addr(&self, _default_listen_port: u16) -> Result> { let interface = rpc_interface( self.rpc_external, self.unsafe_rpc_external, @@ -377,48 +344,25 @@ impl CliConfiguration for RunCmd { self.validator, )?; - Ok(Some(SocketAddr::new(interface, self.rpc_port.unwrap_or(default_listen_port)))) - } - - fn rpc_ipc(&self) -> Result> { - Ok(self.ipc_path.clone()) - } - - fn rpc_ws(&self, default_listen_port: u16) -> Result> { - let interface = rpc_interface( - self.ws_external, - self.unsafe_ws_external, - self.rpc_methods, - self.validator, - )?; - - Ok(Some(SocketAddr::new(interface, self.ws_port.unwrap_or(default_listen_port)))) + Ok(Some(SocketAddr::new(interface, self.rpc_port))) } fn rpc_methods(&self) -> Result { Ok(self.rpc_methods.into()) } - fn rpc_max_payload(&self) -> Result> { - Ok(self.rpc_max_payload) - } - - fn rpc_max_request_size(&self) -> Result> { + fn rpc_max_request_size(&self) -> Result { Ok(self.rpc_max_request_size) } - fn rpc_max_response_size(&self) -> Result> { + fn rpc_max_response_size(&self) -> Result { Ok(self.rpc_max_response_size) } - fn rpc_max_subscriptions_per_connection(&self) -> Result> { + fn rpc_max_subscriptions_per_connection(&self) -> Result { Ok(self.rpc_max_subscriptions_per_connection) } - fn ws_max_out_buffer_capacity(&self) -> Result> { - Ok(self.ws_max_out_buffer_capacity) - } - fn transaction_pool(&self, is_dev: bool) -> Result { Ok(self.pool_config.transaction_pool(is_dev)) } @@ -475,7 +419,7 @@ fn rpc_interface( ) -> Result { if is_external && is_validator && rpc_methods != RpcMethods::Unsafe { return Err(Error::Input( - "--rpc-external and --ws-external options shouldn't be used if the node is running as \ + "--rpc-external option shouldn't be used if the node is running as \ a validator. Use `--unsafe-rpc-external` or `--rpc-methods=unsafe` if you understand \ the risks. See the options description for more information." .to_owned(), diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 063b2c39839f4..92b1eea7ae266 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -57,20 +57,13 @@ pub trait DefaultConfigurationValues { 30333 } - /// The port Substrate should listen on for websocket connections. + /// The port Substrate should listen on for JSON-RPC connections. /// /// By default this is `9944`. - fn rpc_ws_listen_port() -> u16 { + fn rpc_listen_port() -> u16 { 9944 } - /// The port Substrate should listen on for http connections. - /// - /// By default this is `9933`. - fn rpc_http_listen_port() -> u16 { - 9933 - } - /// The port Substrate should listen on for prometheus connections. /// /// By default this is `9615`. @@ -302,24 +295,8 @@ pub trait CliConfiguration: Sized { .unwrap_or_default()) } - /// Get the RPC HTTP address (`None` if disabled). - /// - /// By default this is `None`. - fn rpc_http(&self, _default_listen_port: u16) -> Result> { - Ok(None) - } - - /// Get the RPC IPC path (`None` if disabled). - /// - /// By default this is `None`. - fn rpc_ipc(&self) -> Result> { - Ok(None) - } - - /// Get the RPC websocket address (`None` if disabled). - /// - /// By default this is `None`. - fn rpc_ws(&self, _default_listen_port: u16) -> Result> { + /// Get the RPC address. + fn rpc_addr(&self, _default_listen_port: u16) -> Result> { Ok(None) } @@ -331,11 +308,9 @@ pub trait CliConfiguration: Sized { Ok(Default::default()) } - /// Get the RPC websockets maximum connections (`None` if unlimited). - /// - /// By default this is `None`. - fn rpc_ws_max_connections(&self) -> Result> { - Ok(None) + /// Get the maximum number of RPC server connections. + fn rpc_max_connections(&self) -> Result { + Ok(Default::default()) } /// Get the RPC cors (`None` if disabled) @@ -345,29 +320,19 @@ pub trait CliConfiguration: Sized { Ok(Some(Vec::new())) } - /// Get maximum RPC payload. - fn rpc_max_payload(&self) -> Result> { - Ok(None) - } - /// Get maximum RPC request payload size. - fn rpc_max_request_size(&self) -> Result> { - Ok(None) + fn rpc_max_request_size(&self) -> Result { + Ok(Default::default()) } /// Get maximum RPC response payload size. - fn rpc_max_response_size(&self) -> Result> { - Ok(None) + fn rpc_max_response_size(&self) -> Result { + Ok(Default::default()) } /// Get maximum number of subscriptions per connection. - fn rpc_max_subscriptions_per_connection(&self) -> Result> { - Ok(None) - } - - /// Get maximum WS output buffer capacity. - fn ws_max_out_buffer_capacity(&self) -> Result> { - Ok(None) + fn rpc_max_subscriptions_per_connection(&self) -> Result { + Ok(Default::default()) } /// Get the prometheus configuration (`None` if disabled) @@ -532,18 +497,14 @@ pub trait CliConfiguration: Sized { wasm_method: self.wasm_method()?, wasm_runtime_overrides: self.wasm_runtime_overrides(), execution_strategies: self.execution_strategies(is_dev, is_validator)?, - rpc_http: self.rpc_http(DCV::rpc_http_listen_port())?, - rpc_ws: self.rpc_ws(DCV::rpc_ws_listen_port())?, - rpc_ipc: self.rpc_ipc()?, + rpc_addr: self.rpc_addr(DCV::rpc_listen_port())?, rpc_methods: self.rpc_methods()?, - rpc_ws_max_connections: self.rpc_ws_max_connections()?, + rpc_max_connections: self.rpc_max_connections()?, rpc_cors: self.rpc_cors(is_dev)?, - rpc_max_payload: self.rpc_max_payload()?, rpc_max_request_size: self.rpc_max_request_size()?, rpc_max_response_size: self.rpc_max_response_size()?, rpc_id_provider: None, rpc_max_subs_per_conn: self.rpc_max_subscriptions_per_connection()?, - ws_max_out_buffer_capacity: self.ws_max_out_buffer_capacity()?, prometheus_config: self .prometheus_config(DCV::prometheus_listen_port(), &chain_spec)?, telemetry_endpoints, diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index a8b75f2665aea..9db078046e3c5 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -287,18 +287,14 @@ mod tests { wasm_method: Default::default(), wasm_runtime_overrides: None, execution_strategies: Default::default(), - rpc_http: None, - rpc_ws: None, - rpc_ipc: None, - rpc_ws_max_connections: None, + rpc_addr: None, + rpc_max_connections: Default::default(), rpc_cors: None, rpc_methods: Default::default(), - rpc_max_payload: None, - rpc_max_request_size: None, - rpc_max_response_size: None, - rpc_id_provider: None, - rpc_max_subs_per_conn: None, - ws_max_out_buffer_capacity: None, + rpc_max_request_size: Default::default(), + rpc_max_response_size: Default::default(), + rpc_id_provider: Default::default(), + rpc_max_subs_per_conn: Default::default(), prometheus_config: None, telemetry_endpoints: None, default_heap_pages: None, diff --git a/client/rpc-servers/src/lib.rs b/client/rpc-servers/src/lib.rs index 62a9b4fc4a0ea..92b31937a0cbb 100644 --- a/client/rpc-servers/src/lib.rs +++ b/client/rpc-servers/src/lib.rs @@ -20,6 +20,9 @@ #![warn(missing_docs)] +pub mod middleware; + +use http::header::HeaderValue; use jsonrpsee::{ server::{ middleware::proxy_get_request::ProxyGetRequestLayer, AllowHosts, ServerBuilder, @@ -28,119 +31,62 @@ use jsonrpsee::{ RpcModule, }; use std::{error::Error as StdError, net::SocketAddr}; +use tower_http::cors::{AllowOrigin, CorsLayer}; pub use crate::middleware::RpcMetrics; -use http::header::HeaderValue; pub use jsonrpsee::core::{ id_providers::{RandomIntegerIdProvider, RandomStringIdProvider}, traits::IdProvider, }; -use tower_http::cors::{AllowOrigin, CorsLayer}; - -const MEGABYTE: usize = 1024 * 1024; - -/// Maximal payload accepted by RPC servers. -pub const RPC_MAX_PAYLOAD_DEFAULT: usize = 15 * MEGABYTE; - -/// Default maximum number of connections for WS RPC servers. -const WS_MAX_CONNECTIONS: usize = 100; -/// Default maximum number subscriptions per connection for WS RPC servers. -const WS_MAX_SUBS_PER_CONN: usize = 1024; +const MEGABYTE: u32 = 1024 * 1024; -pub mod middleware; - -/// Type alias JSON-RPC server +/// Type alias for the JSON-RPC server. pub type Server = ServerHandle; -/// Server config. -#[derive(Debug, Clone)] -pub struct WsConfig { +/// RPC server configuration. +#[derive(Debug)] +pub struct Config<'a, M: Send + Sync + 'static> { + /// Socket addresses. + pub addrs: [SocketAddr; 2], + /// CORS. + pub cors: Option<&'a Vec>, /// Maximum connections. - pub max_connections: Option, + pub max_connections: u32, /// Maximum subscriptions per connection. - pub max_subs_per_conn: Option, + pub max_subs_per_conn: u32, /// Maximum rpc request payload size. - pub max_payload_in_mb: Option, + pub max_payload_in_mb: u32, /// Maximum rpc response payload size. - pub max_payload_out_mb: Option, -} - -impl WsConfig { - // Deconstructs the config to get the finalized inner values. - // - // `Payload size` or `max subs per connection` bigger than u32::MAX will be truncated. - fn deconstruct(self) -> (u32, u32, u32, u32) { - let max_conns = self.max_connections.unwrap_or(WS_MAX_CONNECTIONS) as u32; - let max_payload_in_mb = payload_size_or_default(self.max_payload_in_mb) as u32; - let max_payload_out_mb = payload_size_or_default(self.max_payload_out_mb) as u32; - let max_subs_per_conn = self.max_subs_per_conn.unwrap_or(WS_MAX_SUBS_PER_CONN) as u32; - - (max_payload_in_mb, max_payload_out_mb, max_conns, max_subs_per_conn) - } -} - -/// Start HTTP server listening on given address. -pub async fn start_http( - addrs: [SocketAddr; 2], - cors: Option<&Vec>, - max_payload_in_mb: Option, - max_payload_out_mb: Option, - metrics: Option, - rpc_api: RpcModule, - rt: tokio::runtime::Handle, -) -> Result> { - let max_payload_in = payload_size_or_default(max_payload_in_mb) as u32; - let max_payload_out = payload_size_or_default(max_payload_out_mb) as u32; - let host_filter = hosts_filter(cors.is_some(), &addrs); - - let middleware = tower::ServiceBuilder::new() - // Proxy `GET /health` requests to internal `system_health` method. - .layer(ProxyGetRequestLayer::new("/health", "system_health")?) - .layer(try_into_cors(cors)?); - - let builder = ServerBuilder::new() - .max_request_body_size(max_payload_in) - .max_response_body_size(max_payload_out) - .set_host_filtering(host_filter) - .set_middleware(middleware) - .custom_tokio_runtime(rt) - .http_only(); - - let rpc_api = build_rpc_api(rpc_api); - let (handle, addr) = if let Some(metrics) = metrics { - let server = builder.set_logger(metrics).build(&addrs[..]).await?; - let addr = server.local_addr(); - (server.start(rpc_api)?, addr) - } else { - let server = builder.build(&addrs[..]).await?; - let addr = server.local_addr(); - (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()), - format_cors(cors) - ); - - Ok(handle) + pub max_payload_out_mb: u32, + /// Metrics. + pub metrics: Option, + /// RPC API. + pub rpc_api: RpcModule, + /// Subscription ID provider. + pub id_provider: Option>, + /// Tokio runtime handle. + pub tokio_handle: tokio::runtime::Handle, } -/// Start a JSON-RPC server listening on given address that supports both HTTP and WS. -pub async fn start( - addrs: [SocketAddr; 2], - cors: Option<&Vec>, - ws_config: WsConfig, - metrics: Option, - rpc_api: RpcModule, - rt: tokio::runtime::Handle, - id_provider: Option>, +/// Start RPC server listening on given address. +pub async fn start_server( + config: Config<'_, M>, ) -> Result> { - let (max_payload_in, max_payload_out, max_connections, max_subs_per_conn) = - ws_config.deconstruct(); - - let host_filter = hosts_filter(cors.is_some(), &addrs); + let Config { + addrs, + cors, + max_payload_in_mb, + max_payload_out_mb, + max_connections, + max_subs_per_conn, + metrics, + id_provider, + tokio_handle, + rpc_api, + } = config; + + let host_filter = hosts_filtering(cors.is_some(), &addrs); let middleware = tower::ServiceBuilder::new() // Proxy `GET /health` requests to internal `system_health` method. @@ -148,14 +94,14 @@ pub async fn start( .layer(try_into_cors(cors)?); let mut builder = ServerBuilder::new() - .max_request_body_size(max_payload_in) - .max_response_body_size(max_payload_out) + .max_request_body_size(max_payload_in_mb.saturating_mul(MEGABYTE)) + .max_response_body_size(max_payload_out_mb.saturating_mul(MEGABYTE)) .max_connections(max_connections) .max_subscriptions_per_connection(max_subs_per_conn) .ping_interval(std::time::Duration::from_secs(30)) .set_host_filtering(host_filter) .set_middleware(middleware) - .custom_tokio_runtime(rt); + .custom_tokio_runtime(tokio_handle); if let Some(provider) = id_provider { builder = builder.set_id_provider(provider); @@ -175,7 +121,7 @@ pub async fn start( }; log::info!( - "Running JSON-RPC WS server: addr={}, allowed origins={}", + "Running JSON-RPC server: addr={}, allowed origins={}", addr.map_or_else(|_| "unknown".to_string(), |a| a.to_string()), format_cors(cors) ); @@ -183,6 +129,20 @@ pub async fn start( Ok(handle) } +fn hosts_filtering(enabled: bool, addrs: &[SocketAddr]) -> AllowHosts { + if enabled { + // NOTE The listening addresses are whitelisted by default. + let mut hosts = Vec::with_capacity(addrs.len() * 2); + for addr in addrs { + hosts.push(format!("localhost:{}", addr.port()).into()); + hosts.push(format!("127.0.0.1:{}", addr.port()).into()); + } + AllowHosts::Only(hosts) + } else { + AllowHosts::Any + } +} + fn build_rpc_api(mut rpc_api: RpcModule) -> RpcModule { let mut available_methods = rpc_api.method_names().collect::>(); available_methods.sort(); @@ -198,24 +158,6 @@ fn build_rpc_api(mut rpc_api: RpcModule) -> RpcModu rpc_api } -fn payload_size_or_default(size_mb: Option) -> usize { - size_mb.map_or(RPC_MAX_PAYLOAD_DEFAULT, |mb| mb.saturating_mul(MEGABYTE)) -} - -fn hosts_filter(enabled: bool, addrs: &[SocketAddr]) -> AllowHosts { - if enabled { - // NOTE The listening addresses are whitelisted by default. - let mut hosts = Vec::with_capacity(addrs.len() * 2); - for addr in addrs { - hosts.push(format!("localhost:{}", addr.port()).into()); - hosts.push(format!("127.0.0.1:{}", addr.port()).into()); - } - AllowHosts::Only(hosts) - } else { - AllowHosts::Any - } -} - fn try_into_cors( maybe_cors: Option<&Vec>, ) -> Result> { diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 6550fcdd8ef4f..40f8c6a4f0445 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -83,34 +83,24 @@ pub struct Configuration { pub wasm_runtime_overrides: Option, /// Execution strategies. pub execution_strategies: ExecutionStrategies, - /// RPC over HTTP binding address. `None` if disabled. - pub rpc_http: Option, - /// RPC over Websockets binding address. `None` if disabled. - pub rpc_ws: Option, - /// RPC over IPC binding path. `None` if disabled. - pub rpc_ipc: Option, - /// Maximum number of connections for WebSockets RPC server. `None` if default. - pub rpc_ws_max_connections: Option, + /// JSON-RPC server binding address. + pub rpc_addr: Option, + /// Maximum number of connections for JSON-RPC server. + pub rpc_max_connections: u32, /// CORS settings for HTTP & WS servers. `None` if all origins are allowed. pub rpc_cors: Option>, /// RPC methods to expose (by default only a safe subset or all of them). pub rpc_methods: RpcMethods, - /// Maximum payload of rpc request/responses. - pub rpc_max_payload: Option, /// Maximum payload of a rpc request - pub rpc_max_request_size: Option, - /// Maximum payload of a rpc request - pub rpc_max_response_size: Option, + pub rpc_max_request_size: u32, + /// Maximum payload of a rpc response. + pub rpc_max_response_size: u32, /// Custom JSON-RPC subscription ID provider. /// /// Default: [`crate::RandomStringSubscriptionId`]. pub rpc_id_provider: Option>, /// Maximum allowed subscriptions per rpc connection - /// - /// Default: 1024. - pub rpc_max_subs_per_conn: Option, - /// Maximum size of the output buffer capacity for websocket connections. - pub ws_max_out_buffer_capacity: Option, + pub rpc_max_subs_per_conn: u32, /// Prometheus endpoint configuration. `None` if disabled. pub prometheus_config: Option, /// Telemetry service URL. `None` if disabled. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index c0c7c537c64dc..a5667717055b5 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -380,57 +380,37 @@ where } } - let (max_request_size, ws_max_response_size, http_max_response_size) = - legacy_cli_parsing(config); - - let random_port = |mut addr: SocketAddr| { + // if binding the specified port failed then a random port is assigned by the OS. + let backup_port = |mut addr: SocketAddr| { addr.set_port(0); addr }; - 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 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 addr = config.rpc_addr.unwrap_or(([127, 0, 0, 1], 9944).into()); + let backup_addr = backup_port(addr); let metrics = sc_rpc_server::RpcMetrics::new(config.prometheus_registry())?; - let server_config = sc_rpc_server::WsConfig { - max_connections: config.rpc_ws_max_connections, - max_payload_in_mb: max_request_size, - max_payload_out_mb: ws_max_response_size, + let server_config = sc_rpc_server::Config { + addrs: [addr, backup_addr], + max_connections: config.rpc_max_connections, + max_payload_in_mb: config.rpc_max_request_size, + max_payload_out_mb: config.rpc_max_response_size, max_subs_per_conn: config.rpc_max_subs_per_conn, + rpc_api: gen_rpc_module(deny_unsafe(addr, &config.rpc_methods))?, + metrics, + id_provider: rpc_id_provider, + cors: config.rpc_cors.as_ref(), + tokio_handle: config.tokio_handle.clone(), }; - let http_fut = sc_rpc_server::start_http( - [http_addr, http_addr2], - config.rpc_cors.as_ref(), - max_request_size, - http_max_response_size, - metrics.clone(), - gen_rpc_module(deny_unsafe(http_addr, &config.rpc_methods))?, - config.tokio_handle.clone(), - ); - - let ws_fut = sc_rpc_server::start( - [ws_addr, ws_addr2], - config.rpc_cors.as_ref(), - server_config.clone(), - metrics.clone(), - gen_rpc_module(deny_unsafe(ws_addr, &config.rpc_methods))?, - config.tokio_handle.clone(), - rpc_id_provider, - ); - + // TODO: https://github.com/paritytech/substrate/issues/13773 + // + // `block_in_place` is a hack to allow callers to call `block_on` prior to + // calling `start_rpc_servers`. match tokio::task::block_in_place(|| { - config.tokio_handle.block_on(futures::future::try_join(http_fut, ws_fut)) + config.tokio_handle.block_on(sc_rpc_server::start_server(server_config)) }) { - Ok((http, ws)) => Ok(Box::new((waiting::Server(Some(http)), waiting::Server(Some(ws))))), + Ok(server) => Ok(Box::new(waiting::Server(Some(server)))), Err(e) => Err(Error::Application(e)), } } @@ -534,51 +514,6 @@ where } } -fn legacy_cli_parsing(config: &Configuration) -> (Option, Option, Option) { - let ws_max_response_size = match ( - config.ws_max_out_buffer_capacity, - config.rpc_max_response_size, - ) { - (Some(legacy_max), max) => { - eprintln!("DEPRECATED: `--ws_max_out_buffer_capacity` has been removed; use `rpc-max-response-size or rpc-max-request-size` instead"); - eprintln!("Setting WS `rpc-max-response-size` to `max(ws_max_out_buffer_capacity, rpc_max_response_size)`"); - Some(std::cmp::max(legacy_max, max.unwrap_or(0))) - }, - (None, Some(m)) => Some(m), - (None, None) => None, - }; - - let max_request_size = match (config.rpc_max_payload, config.rpc_max_request_size) { - (Some(legacy_max), max) => { - eprintln!("DEPRECATED: `--rpc_max_payload` has been removed use `rpc-max-response-size or rpc-max-request-size` instead"); - eprintln!( - "Setting `rpc-max-response-size` to `max(rpc_max_payload, rpc_max_request_size)`" - ); - Some(std::cmp::max(legacy_max, max.unwrap_or(0))) - }, - (None, Some(max)) => Some(max), - (None, None) => None, - }; - - let http_max_response_size = match (config.rpc_max_payload, config.rpc_max_response_size) { - (Some(legacy_max), max) => { - eprintln!("DEPRECATED: `--rpc_max_payload` has been removed use `rpc-max-response-size or rpc-max-request-size` instead"); - eprintln!( - "Setting HTTP `rpc-max-response-size` to `max(rpc_max_payload, rpc_max_response_size)`" - ); - Some(std::cmp::max(legacy_max, max.unwrap_or(0))) - }, - (None, Some(max)) => Some(max), - (None, None) => None, - }; - - if config.rpc_ipc.is_some() { - eprintln!("DEPRECATED: `--ipc-path` has no effect anymore IPC support has been removed"); - } - - (max_request_size, ws_max_response_size, http_max_response_size) -} - #[cfg(test)] mod tests { use super::*; diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 29e68261a1025..0eb4489ad089a 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -246,18 +246,14 @@ fn node_config< wasm_method: Default::default(), wasm_runtime_overrides: Default::default(), execution_strategies: Default::default(), - rpc_http: None, - rpc_ipc: None, - rpc_ws: None, - rpc_ws_max_connections: None, + rpc_addr: Default::default(), + rpc_max_connections: Default::default(), rpc_cors: None, rpc_methods: Default::default(), - rpc_max_payload: None, - rpc_max_request_size: None, - rpc_max_response_size: None, - rpc_id_provider: None, - rpc_max_subs_per_conn: None, - ws_max_out_buffer_capacity: None, + rpc_max_request_size: Default::default(), + rpc_max_response_size: Default::default(), + rpc_id_provider: Default::default(), + rpc_max_subs_per_conn: Default::default(), prometheus_config: None, telemetry_endpoints: None, default_heap_pages: None, diff --git a/test-utils/cli/src/lib.rs b/test-utils/cli/src/lib.rs index 1846f19090b33..f225cc135a2ae 100644 --- a/test-utils/cli/src/lib.rs +++ b/test-utils/cli/src/lib.rs @@ -282,7 +282,7 @@ pub fn extract_info_from_output(read: impl Read + Send) -> (NodeInfo, String) { data.push_str("\n"); // does the line contain our port (we expect this specific output from substrate). - let sock_addr = match line.split_once("Running JSON-RPC WS server: addr=") { + let sock_addr = match line.split_once("Running JSON-RPC server: addr=") { None => return None, Some((_, after)) => after.split_once(",").unwrap().0, };