From dd8a778027f9e4a1958aa99c52bf3cffc2b888aa Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 4 Jun 2019 15:29:31 +1200 Subject: [PATCH] Cherry pick upstream (#11) * core: allow setting max ws rpc connections (#2632) * core: allow setting max ws rpc connections * style: break long lines * core: fix service tests * Bump structopt and fix compilation. (#2736) --- Cargo.lock | 14 +++++++------- core/cli/src/lib.rs | 9 +++++---- core/cli/src/params.rs | 31 ++++++++++++++++++++++++++++--- core/rpc-servers/src/lib.rs | 7 ++++++- core/service/src/components.rs | 17 +++++++++++++++-- core/service/src/config.rs | 3 +++ core/service/src/lib.rs | 12 ++++++++++-- core/service/test/src/lib.rs | 1 + 8 files changed, 75 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0ba47ab..6fa2378c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1988,7 +1988,7 @@ dependencies = [ "sr-io 1.0.0", "sr-primitives 1.0.0", "sr-std 1.0.0", - "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-basic-authorship 1.0.0", "substrate-cli 1.0.0", "substrate-client 1.0.0", @@ -3744,16 +3744,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3855,7 +3855,7 @@ dependencies = [ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", - "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 1.0.0", "substrate-keyring 1.0.0", "substrate-network 0.1.0", @@ -5777,8 +5777,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum stream-cipher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8861bc80f649f5b4c9bd38b696ae9af74499d479dbfb327f0607de6b326a36bc" "checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3" -"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" +"checksum structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fa19a5a708e22bb5be31c1b6108a2a902f909c4b9ba85cba44c06632386bc0ff" +"checksum structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d59d0ae8ef8de16e49e3ca7afa16024a3e0dfd974a75ef93fdc5464e34523f" "checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806" "checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579" "checksum substrate-bip39 0.2.0 (git+https://github.com/paritytech/substrate-bip39)" = "" diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index a3e31ddc..834c4d68 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -51,7 +51,7 @@ pub use structopt::clap::App; use params::{ RunCmd, PurgeChainCmd, RevertCmd, ImportBlocksCmd, ExportBlocksCmd, BuildSpecCmd, NetworkConfigurationParams, SharedParams, MergeParameters, TransactionPoolParams, - NodeKeyParams, NodeKeyType + NodeKeyParams, NodeKeyType, Cors, }; pub use params::{NoCustom, CoreParams}; pub use traits::{GetLogFilter, AugmentClap}; @@ -480,11 +480,12 @@ where config.rpc_ws = Some( parse_address(&format!("{}:{}", ws_interface, 9944), cli.ws_port)? ); + config.rpc_ws_max_connections = cli.ws_max_connections; config.rpc_cors = cli.rpc_cors.unwrap_or_else(|| if is_dev { log::warn!("Running in --dev mode, RPC CORS has been disabled."); - None + Cors::All } else { - Some(vec![ + Cors::List(vec![ "http://localhost:*".into(), "http://127.0.0.1:*".into(), "https://localhost:*".into(), @@ -494,7 +495,7 @@ where "https://cennznet-ui.centrality.me".into(), "https://cennznet-ui.centrality.cloud".into(), ]) - }); + }).into(); // Override telemetry if cli.no_telemetry { diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs index 6cb4a606..257d22f6 100644 --- a/core/cli/src/params.rs +++ b/core/cli/src/params.rs @@ -333,13 +333,17 @@ pub struct RunCmd { #[structopt(long = "ws-port", value_name = "PORT")] pub ws_port: Option, + /// Maximum number of WS RPC server connections. + #[structopt(long = "ws-max-connections", value_name = "COUNT")] + pub ws_max_connections: Option, + /// Specify browser Origins allowed to access the HTTP & WS RPC servers. /// It's a comma-separated list of origins (protocol://domain or special `null` value). /// Value of `all` will disable origin validation. /// Default is to allow localhost, https://polkadot.js.org and https://substrate-ui.parity.io origins. /// When running in --dev mode the default is to allow all origins. #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = "parse_cors"))] - pub rpc_cors: Option>>, + pub rpc_cors: Option, /// Specify the pruning mode, a number of blocks to keep or 'archive'. Default is 256. #[structopt(long = "pruning", value_name = "PRUNING_MODE")] @@ -482,8 +486,29 @@ fn parse_telemetry_endpoints(s: &str) -> Result<(String, u8), Box>` +/// handling of `structopt`. +#[derive(Clone, Debug)] +pub enum Cors { + /// All hosts allowed + All, + /// Only hosts on the list are allowed. + List(Vec), +} + +impl From for Option> { + fn from(cors: Cors) -> Self { + match cors { + Cors::All => None, + Cors::List(list) => Some(list), + } + } +} + /// Parse cors origins -fn parse_cors(s: &str) -> Result>, Box> { +fn parse_cors(s: &str) -> Result> { let mut is_all = false; let mut origins = Vec::new(); for part in s.split(',') { @@ -496,7 +521,7 @@ fn parse_cors(s: &str) -> Result>, Box> { } } - Ok(if is_all { None } else { Some(origins) }) + Ok(if is_all { Cors::All } else { Cors::List(origins) }) } impl_augment_clap!(RunCmd); diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index b37895c5..2c0672ac 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -24,9 +24,12 @@ use std::io; use log::error; use sr_primitives::{traits::{Block as BlockT, NumberFor}, generic::SignedBlock}; -/// Maximal payload accepted by RPC servers +/// Maximal payload accepted by RPC servers. const MAX_PAYLOAD: usize = 15 * 1024 * 1024; +/// Default maximum number of connections for WS RPC servers. +const WS_MAX_CONNECTIONS: usize = 100; + type Metadata = apis::metadata::Metadata; type RpcHandler = pubsub::PubSubHandler; pub type HttpServer = http::Server; @@ -76,11 +79,13 @@ pub fn start_http( /// Start WS server listening on given address. pub fn start_ws( addr: &std::net::SocketAddr, + max_connections: Option, cors: Option<&Vec>, io: RpcHandler, ) -> io::Result { ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| Metadata::new(context.sender())) .max_payload(MAX_PAYLOAD) + .max_connections(max_connections.unwrap_or(WS_MAX_CONNECTIONS)) .allowed_origins(map_cors(cors)) .start(addr) .map_err(|err| match err { diff --git a/core/service/src/components.rs b/core/service/src/components.rs index db2aae4c..dbbdc3a1 100644 --- a/core/service/src/components.rs +++ b/core/service/src/components.rs @@ -143,6 +143,7 @@ pub trait StartRPC { system_info: SystemInfo, rpc_http: Option, rpc_ws: Option, + rpc_ws_max_connections: Option, rpc_cors: Option>, task_executor: TaskExecutor, transaction_pool: Arc>, @@ -162,6 +163,7 @@ impl StartRPC for C where rpc_system_info: SystemInfo, rpc_http: Option, rpc_ws: Option, + rpc_ws_max_connections: Option, rpc_cors: Option>, task_executor: TaskExecutor, transaction_pool: Arc>, @@ -186,8 +188,19 @@ impl StartRPC for C where }; Ok(( - maybe_start_server(rpc_http, |address| rpc::start_http(address, rpc_cors.as_ref(), handler()))?, - maybe_start_server(rpc_ws, |address| rpc::start_ws(address, rpc_cors.as_ref(), handler()))?.map(Mutex::new), + maybe_start_server( + rpc_http, + |address| rpc::start_http(address, rpc_cors.as_ref(), handler()), + )?, + maybe_start_server( + rpc_ws, + |address| rpc::start_ws( + address, + rpc_ws_max_connections, + rpc_cors.as_ref(), + handler(), + ), + )?.map(Mutex::new), )) } } diff --git a/core/service/src/config.rs b/core/service/src/config.rs index 20134c78..4ad32fe0 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -66,6 +66,8 @@ pub struct Configuration { pub rpc_http: Option, /// RPC over Websockets binding address. `None` if disabled. pub rpc_ws: Option, + /// Maximum number of connections for WebSockets RPC server. `None` if default. + pub rpc_ws_max_connections: Option, /// CORS settings for HTTP & WS servers. `None` if all origins are allowed. pub rpc_cors: Option>, /// Telemetry service URL. `None` if disabled. @@ -102,6 +104,7 @@ impl Configuration Service { properties: config.chain_spec.properties(), }; let rpc = Components::RuntimeServices::start_rpc( - client.clone(), network.clone(), has_bootnodes, system_info, config.rpc_http, - config.rpc_ws, config.rpc_cors.clone(), task_executor.clone(), transaction_pool.clone(), + client.clone(), + network.clone(), + has_bootnodes, + system_info, + config.rpc_http, + config.rpc_ws, + config.rpc_ws_max_connections, + config.rpc_cors.clone(), + task_executor.clone(), + transaction_pool.clone(), )?; let telemetry_connection_sinks: Arc>>> = Default::default(); diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 95cd0173..c700f49b 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -121,6 +121,7 @@ fn node_config ( execution_strategies: Default::default(), rpc_http: None, rpc_ws: None, + rpc_ws_max_connections: None, rpc_cors: None, telemetry_endpoints: None, default_heap_pages: None,