mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
Allow to expose a subset of unsafe RPCs (#5233)
* sc-cli: Use type-safe constructors for RPC/Prometheus interfaces * service: Simplify rpc handler creation Could probably be further simplifies once [this][commit] lands. [commit]: https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf * service: Streamline some HTTP & WS server start logic * client: Introduce a simple RPC policy mechanism * rpc/system: Check unsafe RPCs * rpc/offchain: Check unsafe RPCs * rpc/author: Check unsafe RPCs
This commit is contained in:
@@ -46,6 +46,7 @@ use sp_runtime::traits::{
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sc_executor::{NativeExecutor, NativeExecutionDispatch};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::{Read, Write, Seek},
|
||||
marker::PhantomData, sync::Arc, pin::Pin
|
||||
};
|
||||
@@ -1001,7 +1002,7 @@ ServiceBuilder<
|
||||
|
||||
// RPC
|
||||
let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc");
|
||||
let gen_handler = || {
|
||||
let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| {
|
||||
use sc_rpc::{chain, state, author, system, offchain};
|
||||
|
||||
let system_info = sc_rpc::system::SystemInfo {
|
||||
@@ -1043,32 +1044,31 @@ ServiceBuilder<
|
||||
transaction_pool.clone(),
|
||||
subscriptions,
|
||||
keystore.clone(),
|
||||
deny_unsafe,
|
||||
);
|
||||
let system = system::System::new(system_info, system_rpc_tx.clone());
|
||||
let system = system::System::new(system_info, system_rpc_tx.clone(), deny_unsafe);
|
||||
|
||||
match offchain_storage.clone() {
|
||||
Some(storage) => {
|
||||
let offchain = sc_rpc::offchain::Offchain::new(storage);
|
||||
sc_rpc_server::rpc_handler((
|
||||
state::StateApi::to_delegate(state),
|
||||
chain::ChainApi::to_delegate(chain),
|
||||
offchain::OffchainApi::to_delegate(offchain),
|
||||
author::AuthorApi::to_delegate(author),
|
||||
system::SystemApi::to_delegate(system),
|
||||
rpc_extensions.clone(),
|
||||
))
|
||||
},
|
||||
None => sc_rpc_server::rpc_handler((
|
||||
state::StateApi::to_delegate(state),
|
||||
chain::ChainApi::to_delegate(chain),
|
||||
author::AuthorApi::to_delegate(author),
|
||||
system::SystemApi::to_delegate(system),
|
||||
rpc_extensions.clone(),
|
||||
))
|
||||
}
|
||||
let maybe_offchain_rpc = offchain_storage.clone()
|
||||
.map(|storage| {
|
||||
let offchain = sc_rpc::offchain::Offchain::new(storage, deny_unsafe);
|
||||
// FIXME: Use plain Option (don't collect into HashMap) when we upgrade to jsonrpc 14.1
|
||||
// https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf
|
||||
let delegate = offchain::OffchainApi::to_delegate(offchain);
|
||||
delegate.into_iter().collect::<HashMap<_, _>>()
|
||||
}).unwrap_or_default();
|
||||
|
||||
sc_rpc_server::rpc_handler((
|
||||
state::StateApi::to_delegate(state),
|
||||
chain::ChainApi::to_delegate(chain),
|
||||
maybe_offchain_rpc,
|
||||
author::AuthorApi::to_delegate(author),
|
||||
system::SystemApi::to_delegate(system),
|
||||
rpc_extensions.clone(),
|
||||
))
|
||||
};
|
||||
let rpc_handlers = gen_handler();
|
||||
let rpc = start_rpc_servers(&config, gen_handler)?;
|
||||
// This is used internally, so don't restrict access to unsafe RPC
|
||||
let rpc_handlers = gen_handler(sc_rpc::DenyUnsafe::No);
|
||||
|
||||
spawn_handle.spawn(
|
||||
"network-worker",
|
||||
|
||||
@@ -59,6 +59,8 @@ pub struct Configuration {
|
||||
pub wasm_method: WasmExecutionMethod,
|
||||
/// Execution strategies.
|
||||
pub execution_strategies: ExecutionStrategies,
|
||||
/// Whether potentially unsafe RPC is considered safe to be exposed.
|
||||
pub unsafe_rpc_expose: bool,
|
||||
/// RPC over HTTP binding address. `None` if disabled.
|
||||
pub rpc_http: Option<SocketAddr>,
|
||||
/// RPC over Websockets binding address. `None` if disabled.
|
||||
|
||||
@@ -511,7 +511,7 @@ mod waiting {
|
||||
|
||||
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
fn start_rpc_servers<H: FnMut(sc_rpc::DenyUnsafe) -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
config: &Configuration,
|
||||
mut gen_handler: H
|
||||
) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
|
||||
@@ -533,10 +533,23 @@ fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
})
|
||||
}
|
||||
|
||||
fn deny_unsafe(addr: &Option<SocketAddr>, unsafe_rpc_expose: bool) -> sc_rpc::DenyUnsafe {
|
||||
let is_exposed_addr = addr.map(|x| x.ip().is_loopback()).unwrap_or(false);
|
||||
if is_exposed_addr && !unsafe_rpc_expose {
|
||||
sc_rpc::DenyUnsafe::Yes
|
||||
} else {
|
||||
sc_rpc::DenyUnsafe::No
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Box::new((
|
||||
maybe_start_server(
|
||||
config.rpc_http,
|
||||
|address| sc_rpc_server::start_http(address, config.rpc_cors.as_ref(), gen_handler()),
|
||||
|address| sc_rpc_server::start_http(
|
||||
address,
|
||||
config.rpc_cors.as_ref(),
|
||||
gen_handler(deny_unsafe(&config.rpc_http, config.unsafe_rpc_expose)),
|
||||
),
|
||||
)?.map(|s| waiting::HttpServer(Some(s))),
|
||||
maybe_start_server(
|
||||
config.rpc_ws,
|
||||
@@ -544,15 +557,15 @@ fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
address,
|
||||
config.rpc_ws_max_connections,
|
||||
config.rpc_cors.as_ref(),
|
||||
gen_handler(),
|
||||
gen_handler(deny_unsafe(&config.rpc_ws, config.unsafe_rpc_expose)),
|
||||
),
|
||||
)?.map(|s| waiting::WsServer(Some(s))).map(Mutex::new),
|
||||
)?.map(|s| waiting::WsServer(Some(s))),
|
||||
)))
|
||||
}
|
||||
|
||||
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
|
||||
#[cfg(target_os = "unknown")]
|
||||
fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
fn start_rpc_servers<H: FnMut(sc_rpc::DenyUnsafe) -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
|
||||
_: &Configuration,
|
||||
_: H
|
||||
) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
|
||||
|
||||
Reference in New Issue
Block a user