Skip to content
Snippets Groups Projects
Unverified Commit 76f297da authored by PG Herveou's avatar PG Herveou Committed by GitHub
Browse files

[eth-rpc] proxy /health (#6360)


make the eth-rpc proxy /health and /health/readiness from the proxied
substrate chain
see #4802

---------

Co-authored-by: default avatarGitHub Action <action@github.com>
parent 32e116a6
No related merge requests found
Pipeline #504335 waiting for manual action with stages
in 33 minutes and 53 seconds
......@@ -12562,6 +12562,7 @@ dependencies = [
"rlp 0.6.1",
"sc-cli",
"sc-rpc",
"sc-rpc-api",
"sc-service",
"scale-info",
"secp256k1",
......
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
......@@ -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 }
......
......@@ -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;
......@@ -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())),
}
};
......@@ -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)
}
......@@ -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,
......@@ -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>,
......@@ -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,
......
......@@ -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::*;
......
// 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% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment