Add IPC support (#6348)

This is useful for both security and performance reasons. IPC is faster
than TCP, and it is subject to OS access controls.
This commit is contained in:
Demi Obenour
2020-06-16 10:14:12 +00:00
committed by GitHub
parent e99ff8ee96
commit e2f5e4bd74
10 changed files with 136 additions and 1 deletions
+6
View File
@@ -285,6 +285,12 @@ macro_rules! substrate_cli_subcommands {
}
}
fn rpc_ipc(&self) -> $crate::Result<::std::option::Option<::std::string::String>> {
match self {
$($enum::$variant(cmd) => cmd.rpc_ipc()),*
}
}
fn rpc_http(&self) -> $crate::Result<::std::option::Option<::std::net::SocketAddr>> {
match self {
$($enum::$variant(cmd) => cmd.rpc_http()),*
@@ -122,6 +122,10 @@ pub struct RunCmd {
#[structopt(long = "prometheus-external")]
pub prometheus_external: bool,
/// Specify IPC RPC server path
#[structopt(long = "ipc-path", value_name = "PATH")]
pub ipc_path: Option<String>,
/// Specify HTTP RPC server TCP port.
#[structopt(long = "rpc-port", value_name = "PORT")]
pub rpc_port: Option<u16>,
@@ -434,6 +438,10 @@ impl CliConfiguration for RunCmd {
Ok(Some(SocketAddr::new(interface, self.rpc_port.unwrap_or(9933))))
}
fn rpc_ipc(&self) -> Result<Option<String>> {
Ok(self.ipc_path.clone())
}
fn rpc_ws(&self) -> Result<Option<SocketAddr>> {
let interface = rpc_interface(
self.ws_external,
+8
View File
@@ -264,6 +264,13 @@ pub trait CliConfiguration: Sized {
Ok(Default::default())
}
/// Get the RPC IPC path (`None` if disabled).
///
/// By default this is `None`.
fn rpc_ipc(&self) -> Result<Option<String>> {
Ok(Default::default())
}
/// Get the RPC websocket address (`None` if disabled).
///
/// By default this is `None`.
@@ -451,6 +458,7 @@ pub trait CliConfiguration: Sized {
execution_strategies: self.execution_strategies(is_dev, is_validator)?,
rpc_http: self.rpc_http()?,
rpc_ws: self.rpc_ws()?,
rpc_ipc: self.rpc_ipc()?,
rpc_methods: self.rpc_methods()?,
rpc_ws_max_connections: self.rpc_ws_max_connections()?,
rpc_cors: self.rpc_cors(is_dev)?,
+1
View File
@@ -22,3 +22,4 @@ sp-runtime = { version = "2.0.0-rc3", path = "../../primitives/runtime" }
[target.'cfg(not(target_os = "unknown"))'.dependencies]
http = { package = "jsonrpc-http-server", version = "14.2.0" }
ws = { package = "jsonrpc-ws-server", version = "14.2.0" }
ipc = { version = "14.2.0", package = "jsonrpc-ipc-server" }
+19
View File
@@ -62,6 +62,8 @@ pub fn rpc_handler<M: PubSubMetadata>(
mod inner {
use super::*;
/// Type alias for ipc server
pub type IpcServer = ipc::Server;
/// Type alias for http server
pub type HttpServer = http::Server;
/// Type alias for ws server
@@ -89,6 +91,23 @@ mod inner {
.start_http(addr)
}
/// Start IPC server listening on given path.
///
/// **Note**: Only available if `not(target_os = "unknown")`.
pub fn start_ipc<M: pubsub::PubSubMetadata + Default>(
addr: &str,
io: RpcHandler<M>,
) -> io::Result<ipc::Server> {
let builder = ipc::ServerBuilder::new(io);
#[cfg(target_os = "unix")]
builder.set_security_attributes({
let security_attributes = ipc::SecurityAttributes::empty();
security_attributes.set_mode(0o600)?;
security_attributes
});
builder.start(addr)
}
/// Start WS server listening on given address.
///
/// **Note**: Only available if `not(target_os = "unknown")`.
+2
View File
@@ -67,6 +67,8 @@ pub struct Configuration {
pub rpc_http: Option<SocketAddr>,
/// RPC over Websockets binding address. `None` if disabled.
pub rpc_ws: Option<SocketAddr>,
/// RPC over IPC binding path. `None` if disabled.
pub rpc_ipc: Option<String>,
/// Maximum number of connections for WebSockets RPC server. `None` if default.
pub rpc_ws_max_connections: Option<usize>,
/// CORS settings for HTTP & WS servers. `None` if all origins are allowed.
+11
View File
@@ -510,6 +510,16 @@ mod waiting {
}
}
pub struct IpcServer(pub Option<sc_rpc_server::IpcServer>);
impl Drop for IpcServer {
fn drop(&mut self) {
if let Some(server) = self.0.take() {
server.close_handle().close();
let _ = server.wait();
}
}
}
pub struct WsServer(pub Option<sc_rpc_server::WsServer>);
impl Drop for WsServer {
fn drop(&mut self) {
@@ -555,6 +565,7 @@ fn start_rpc_servers<H: FnMut(sc_rpc::DenyUnsafe) -> sc_rpc_server::RpcHandler<s
}
Ok(Box::new((
config.rpc_ipc.as_ref().map(|path| sc_rpc_server::start_ipc(&*path, gen_handler(sc_rpc::DenyUnsafe::No))),
maybe_start_server(
config.rpc_http,
|address| sc_rpc_server::start_http(
+1
View File
@@ -194,6 +194,7 @@ fn node_config<G: RuntimeGenesis + 'static, E: ChainSpecExtension + Clone + 'sta
wasm_method: sc_service::config::WasmExecutionMethod::Interpreted,
execution_strategies: Default::default(),
rpc_http: None,
rpc_ipc: None,
rpc_ws: None,
rpc_ws_max_connections: None,
rpc_cors: None,