Skip to content

Commit 4672a24

Browse files
[stable2412] Backport #6652 (#6876)
Backport #6652 into `stable2412` from niklasad1. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> Co-authored-by: Niklas Adolfsson <[email protected]>
1 parent ba9b9e5 commit 4672a24

File tree

3 files changed

+69
-55
lines changed

3 files changed

+69
-55
lines changed

prdoc/pr_6652.prdoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
2+
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
3+
4+
title: "rpc server: re-use server builder per rpc interface"
5+
6+
doc:
7+
- audience: Node Dev
8+
description: |
9+
This changes that the RPC server builder is re-used for each RPC interface which is more efficient than to build it for every connection.
10+
11+
crates:
12+
- name: sc-rpc-server
13+
bump: patch

substrate/client/rpc-servers/src/lib.rs

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,56 @@ where
144144
local_addrs.push(local_addr);
145145
let cfg = cfg.clone();
146146

147-
let id_provider2 = id_provider.clone();
147+
let RpcSettings {
148+
batch_config,
149+
max_connections,
150+
max_payload_in_mb,
151+
max_payload_out_mb,
152+
max_buffer_capacity_per_connection,
153+
max_subscriptions_per_connection,
154+
rpc_methods,
155+
rate_limit_trust_proxy_headers,
156+
rate_limit_whitelisted_ips,
157+
host_filter,
158+
cors,
159+
rate_limit,
160+
} = listener.rpc_settings();
161+
162+
let http_middleware = tower::ServiceBuilder::new()
163+
.option_layer(host_filter)
164+
// Proxy `GET /health, /health/readiness` requests to the internal
165+
// `system_health` method.
166+
.layer(NodeHealthProxyLayer::default())
167+
.layer(cors);
168+
169+
let mut builder = jsonrpsee::server::Server::builder()
170+
.max_request_body_size(max_payload_in_mb.saturating_mul(MEGABYTE))
171+
.max_response_body_size(max_payload_out_mb.saturating_mul(MEGABYTE))
172+
.max_connections(max_connections)
173+
.max_subscriptions_per_connection(max_subscriptions_per_connection)
174+
.enable_ws_ping(
175+
PingConfig::new()
176+
.ping_interval(Duration::from_secs(30))
177+
.inactive_limit(Duration::from_secs(60))
178+
.max_failures(3),
179+
)
180+
.set_http_middleware(http_middleware)
181+
.set_message_buffer_capacity(max_buffer_capacity_per_connection)
182+
.set_batch_request_config(batch_config)
183+
.custom_tokio_runtime(cfg.tokio_handle.clone());
184+
185+
if let Some(provider) = id_provider.clone() {
186+
builder = builder.set_id_provider(provider);
187+
} else {
188+
builder = builder.set_id_provider(RandomStringIdProvider::new(16));
189+
};
190+
191+
let service_builder = builder.to_service_builder();
192+
let deny_unsafe = deny_unsafe(&local_addr, &rpc_methods);
148193

149194
tokio_handle.spawn(async move {
150195
loop {
151-
let (sock, remote_addr, rpc_cfg) = tokio::select! {
196+
let (sock, remote_addr) = tokio::select! {
152197
res = listener.accept() => {
153198
match res {
154199
Ok(s) => s,
@@ -161,56 +206,10 @@ where
161206
_ = cfg.stop_handle.clone().shutdown() => break,
162207
};
163208

164-
let RpcSettings {
165-
batch_config,
166-
max_connections,
167-
max_payload_in_mb,
168-
max_payload_out_mb,
169-
max_buffer_capacity_per_connection,
170-
max_subscriptions_per_connection,
171-
rpc_methods,
172-
rate_limit_trust_proxy_headers,
173-
rate_limit_whitelisted_ips,
174-
host_filter,
175-
cors,
176-
rate_limit,
177-
} = rpc_cfg;
178-
179-
let http_middleware = tower::ServiceBuilder::new()
180-
.option_layer(host_filter)
181-
// Proxy `GET /health, /health/readiness` requests to the internal
182-
// `system_health` method.
183-
.layer(NodeHealthProxyLayer::default())
184-
.layer(cors);
185-
186-
let mut builder = jsonrpsee::server::Server::builder()
187-
.max_request_body_size(max_payload_in_mb.saturating_mul(MEGABYTE))
188-
.max_response_body_size(max_payload_out_mb.saturating_mul(MEGABYTE))
189-
.max_connections(max_connections)
190-
.max_subscriptions_per_connection(max_subscriptions_per_connection)
191-
.enable_ws_ping(
192-
PingConfig::new()
193-
.ping_interval(Duration::from_secs(30))
194-
.inactive_limit(Duration::from_secs(60))
195-
.max_failures(3),
196-
)
197-
.set_http_middleware(http_middleware)
198-
.set_message_buffer_capacity(max_buffer_capacity_per_connection)
199-
.set_batch_request_config(batch_config)
200-
.custom_tokio_runtime(cfg.tokio_handle.clone());
201-
202-
if let Some(provider) = id_provider2.clone() {
203-
builder = builder.set_id_provider(provider);
204-
} else {
205-
builder = builder.set_id_provider(RandomStringIdProvider::new(16));
206-
};
207-
208-
let service_builder = builder.to_service_builder();
209-
let deny_unsafe = deny_unsafe(&local_addr, &rpc_methods);
210-
211209
let ip = remote_addr.ip();
212210
let cfg2 = cfg.clone();
213211
let service_builder2 = service_builder.clone();
212+
let rate_limit_whitelisted_ips2 = rate_limit_whitelisted_ips.clone();
214213

215214
let svc =
216215
tower::service_fn(move |mut req: http::Request<hyper::body::Incoming>| {
@@ -223,14 +222,14 @@ where
223222
let proxy_ip =
224223
if rate_limit_trust_proxy_headers { get_proxy_ip(&req) } else { None };
225224

226-
let rate_limit_cfg = if rate_limit_whitelisted_ips
225+
let rate_limit_cfg = if rate_limit_whitelisted_ips2
227226
.iter()
228227
.any(|ips| ips.contains(proxy_ip.unwrap_or(ip)))
229228
{
230229
log::debug!(target: "rpc", "ip={ip}, proxy_ip={:?} is trusted, disabling rate-limit", proxy_ip);
231230
None
232231
} else {
233-
if !rate_limit_whitelisted_ips.is_empty() {
232+
if !rate_limit_whitelisted_ips2.is_empty() {
234233
log::debug!(target: "rpc", "ip={ip}, proxy_ip={:?} is not trusted, rate-limit enabled", proxy_ip);
235234
}
236235
rate_limit

substrate/client/rpc-servers/src/utils.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,19 @@ pub(crate) struct Listener {
176176

177177
impl Listener {
178178
/// Accepts a new connection.
179-
pub(crate) async fn accept(
180-
&mut self,
181-
) -> std::io::Result<(tokio::net::TcpStream, SocketAddr, RpcSettings)> {
179+
pub(crate) async fn accept(&mut self) -> std::io::Result<(tokio::net::TcpStream, SocketAddr)> {
182180
let (sock, remote_addr) = self.listener.accept().await?;
183-
Ok((sock, remote_addr, self.cfg.clone()))
181+
Ok((sock, remote_addr))
184182
}
185183

186184
/// Returns the local address the listener is bound to.
187185
pub fn local_addr(&self) -> SocketAddr {
188186
self.local_addr
189187
}
188+
189+
pub fn rpc_settings(&self) -> RpcSettings {
190+
self.cfg.clone()
191+
}
190192
}
191193

192194
pub(crate) fn host_filtering(enabled: bool, addr: SocketAddr) -> Option<HostFilterLayer> {

0 commit comments

Comments
 (0)