Skip to content

Commit

Permalink
[eth-rpc] proxy /health (#6360)
Browse files Browse the repository at this point in the history
make the eth-rpc proxy /health and /health/readiness from the proxied
substrate chain
see #4802

---------

Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
pgherveou and actions-user authored Nov 5, 2024
1 parent 32e116a commit 76f297d
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions prdoc/pr_6360.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
title: '[eth-rpc] proxy /health'
doc:
- audience: Runtime Dev
description: |-
make the eth-rpc proxy /health and /health/readiness from the proxied substrate chain
see #4802
crates:
- name: pallet-revive-eth-rpc
bump: minor
1 change: 1 addition & 0 deletions substrate/frame/revive/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ sp-core = { workspace = true, default-features = true }
sp-weights = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
sc-rpc = { workspace = true, default-features = true }
sc-rpc-api = { workspace = true, default-features = true }
sc-cli = { workspace = true, default-features = true }
sc-service = { workspace = true, default-features = true }
prometheus-endpoint = { workspace = true, default-features = true }
Expand Down
15 changes: 12 additions & 3 deletions substrate/frame/revive/rpc/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! The Ethereum JSON-RPC server.
use crate::{client::Client, EthRpcServer, EthRpcServerImpl};
use crate::{
client::Client, EthRpcServer, EthRpcServerImpl, SystemHealthRpcServer,
SystemHealthRpcServerImpl,
};
use clap::Parser;
use futures::{pin_mut, FutureExt};
use jsonrpsee::server::RpcModule;
Expand Down Expand Up @@ -118,7 +121,10 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> {

match tokio_handle.block_on(signals.try_until_signal(fut)) {
Ok(Ok(client)) => rpc_module(is_dev, client),
Ok(Err(err)) => Err(sc_service::Error::Application(err.into())),
Ok(Err(err)) => {
log::error!("Error connecting to the node at {node_rpc_url}: {err}");
Err(sc_service::Error::Application(err.into()))
},
Err(_) => Err(sc_service::Error::Application("Client connection interrupted".into())),
}
};
Expand All @@ -142,11 +148,14 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> {

/// Create the JSON-RPC module.
fn rpc_module(is_dev: bool, client: Client) -> Result<RpcModule<()>, sc_service::Error> {
let eth_api = EthRpcServerImpl::new(client)
let eth_api = EthRpcServerImpl::new(client.clone())
.with_accounts(if is_dev { vec![crate::Account::default()] } else { vec![] })
.into_rpc();

let health_api = SystemHealthRpcServerImpl::new(client).into_rpc();

let mut module = RpcModule::new(());
module.merge(eth_api).map_err(|e| sc_service::Error::Application(e.into()))?;
module.merge(health_api).map_err(|e| sc_service::Error::Application(e.into()))?;
Ok(module)
}
9 changes: 8 additions & 1 deletion substrate/frame/revive/rpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use std::{
};
use subxt::{
backend::{
legacy::LegacyRpcMethods,
legacy::{rpc_methods::SystemHealth, LegacyRpcMethods},
rpc::{
reconnecting_rpc_client::{Client as ReconnectingRpcClient, ExponentialBackoff},
RpcClient,
Expand Down Expand Up @@ -192,6 +192,7 @@ impl<const N: usize> BlockCache<N> {
}

/// A client connect to a node and maintains a cache of the last `CACHE_SIZE` blocks.
#[derive(Clone)]
pub struct Client {
/// The inner state of the client.
inner: Arc<ClientInner>,
Expand Down Expand Up @@ -555,6 +556,12 @@ impl Client {
cache.tx_hashes_by_block_and_index.get(block_hash).map(|v| v.len())
}

/// Get the system health.
pub async fn system_health(&self) -> Result<SystemHealth, ClientError> {
let health = self.inner.rpc.system_health().await?;
Ok(health)
}

/// Get the balance of the given address.
pub async fn balance(
&self,
Expand Down
3 changes: 3 additions & 0 deletions substrate/frame/revive/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub mod subxt_client;
#[cfg(test)]
mod tests;

mod rpc_health;
pub use rpc_health::*;

mod rpc_methods_gen;
pub use rpc_methods_gen::*;

Expand Down
50 changes: 50 additions & 0 deletions substrate/frame/revive/rpc/src/rpc_health.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Heatlh JSON-RPC methods.

use super::*;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use sc_rpc_api::system::helpers::Health;

#[rpc(server, client)]
pub trait SystemHealthRpc {
/// Proxy the substrate chain system_health RPC call.
#[method(name = "system_health")]
async fn system_health(&self) -> RpcResult<Health>;
}

pub struct SystemHealthRpcServerImpl {
client: client::Client,
}

impl SystemHealthRpcServerImpl {
pub fn new(client: client::Client) -> Self {
Self { client }
}
}

#[async_trait]
impl SystemHealthRpcServer for SystemHealthRpcServerImpl {
async fn system_health(&self) -> RpcResult<Health> {
let health = self.client.system_health().await?;
Ok(Health {
peers: health.peers,
is_syncing: health.is_syncing,
should_have_peers: health.should_have_peers,
})
}
}

0 comments on commit 76f297d

Please sign in to comment.