Skip to content

Commit

Permalink
Merge branch 'master' into cl/return-data-api
Browse files Browse the repository at this point in the history
  • Loading branch information
xermicus committed Sep 20, 2024
2 parents a04cfb7 + 5a43147 commit d366111
Show file tree
Hide file tree
Showing 35 changed files with 498 additions and 211 deletions.
267 changes: 135 additions & 132 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ chain-spec-builder = { path = "substrate/bin/utils/chain-spec-builder", default-
chain-spec-guide-runtime = { path = "docs/sdk/src/reference_docs/chain_spec_runtime" }
chrono = { version = "0.4.31" }
cid = { version = "0.9.0" }
clap = { version = "4.5.10" }
clap = { version = "4.5.13" }
clap-num = { version = "1.0.2" }
clap_complete = { version = "4.5.13" }
coarsetime = { version = "0.1.22" }
Expand Down Expand Up @@ -1299,7 +1299,7 @@ substrate-test-runtime-client = { path = "substrate/test-utils/runtime/client" }
substrate-test-runtime-transaction-pool = { path = "substrate/test-utils/runtime/transaction-pool" }
substrate-test-utils = { path = "substrate/test-utils" }
substrate-wasm-builder = { path = "substrate/utils/wasm-builder", default-features = false }
syn = { version = "2.0.65" }
syn = { version = "2.0.77" }
sysinfo = { version = "0.30" }
tar = { version = "0.4" }
tempfile = { version = "3.8.1" }
Expand Down
9 changes: 9 additions & 0 deletions cumulus/client/consensus/common/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ impl RelayChainInterface for Relaychain {
async fn version(&self, _: PHash) -> RelayChainResult<RuntimeVersion> {
unimplemented!("Not needed for test")
}

async fn call_runtime_api(
&self,
_method_name: &'static str,
_hash: PHash,
_payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
unimplemented!("Not needed for test")
}
}

fn sproof_with_best_parent(client: &Client) -> RelayStateSproofBuilder {
Expand Down
9 changes: 9 additions & 0 deletions cumulus/client/network/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ impl RelayChainInterface for DummyRelayChainInterface {
system_version: 1,
})
}

async fn call_runtime_api(
&self,
_method_name: &'static str,
_hash: PHash,
_payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
unimplemented!("Not needed for test")
}
}

fn make_validator_and_api() -> (
Expand Down
9 changes: 9 additions & 0 deletions cumulus/client/pov-recovery/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,15 @@ impl RelayChainInterface for Relaychain {
) -> RelayChainResult<Vec<CoreState<PHash, NumberFor<Block>>>> {
unimplemented!("Not needed for test");
}

async fn call_runtime_api(
&self,
_method_name: &'static str,
_hash: PHash,
_payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
unimplemented!("Not needed for test")
}
}

fn make_candidate_chain(candidate_number_range: Range<u32>) -> Vec<CommittedCandidateReceipt> {
Expand Down
19 changes: 18 additions & 1 deletion cumulus/client/relay-chain-inprocess-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use sc_client_api::{
StorageProof,
};
use sc_telemetry::TelemetryWorkerHandle;
use sp_api::ProvideRuntimeApi;
use sp_api::{CallApiAt, CallApiAtParams, CallContext, ProvideRuntimeApi};
use sp_consensus::SyncOracle;
use sp_core::Pair;
use sp_state_machine::{Backend as StateBackend, StorageValue};
Expand Down Expand Up @@ -180,6 +180,23 @@ impl RelayChainInterface for RelayChainInProcessInterface {
Ok(self.backend.blockchain().info().finalized_hash)
}

async fn call_runtime_api(
&self,
method_name: &'static str,
hash: PHash,
payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
Ok(self.full_client.call_api_at(CallApiAtParams {
at: hash,
function: method_name,
arguments: payload.to_vec(),
overlayed_changes: &Default::default(),
call_context: CallContext::Offchain,
recorder: &None,
extensions: &Default::default(),
})?)
}

async fn is_major_syncing(&self) -> RelayChainResult<bool> {
Ok(self.sync_oracle.is_major_syncing())
}
Expand Down
37 changes: 35 additions & 2 deletions cumulus/client/relay-chain-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ use sc_client_api::StorageProof;
use sp_version::RuntimeVersion;

use async_trait::async_trait;
use codec::Error as CodecError;
use codec::{Decode, Encode, Error as CodecError};
use jsonrpsee_core::ClientError as JsonRpcError;
use sp_api::ApiError;

use cumulus_primitives_core::relay_chain::BlockId;
use cumulus_primitives_core::relay_chain::{BlockId, Hash as RelayHash};
pub use cumulus_primitives_core::{
relay_chain::{
BlockNumber, CommittedCandidateReceipt, CoreState, Hash as PHash, Header as PHeader,
Expand Down Expand Up @@ -117,6 +117,14 @@ pub trait RelayChainInterface: Send + Sync {
/// Get the hash of the finalized block.
async fn finalized_block_hash(&self) -> RelayChainResult<PHash>;

/// Call an arbitrary runtime api. The input and output are SCALE-encoded.
async fn call_runtime_api(
&self,
method_name: &'static str,
hash: RelayHash,
payload: &[u8],
) -> RelayChainResult<Vec<u8>>;

/// Returns the whole contents of the downward message queue for the parachain we are collating
/// for.
///
Expand Down Expand Up @@ -296,6 +304,15 @@ where
(**self).finalized_block_hash().await
}

async fn call_runtime_api(
&self,
method_name: &'static str,
hash: RelayHash,
payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
(**self).call_runtime_api(method_name, hash, payload).await
}

async fn is_major_syncing(&self) -> RelayChainResult<bool> {
(**self).is_major_syncing().await
}
Expand Down Expand Up @@ -364,3 +381,19 @@ where
(**self).version(relay_parent).await
}
}

/// Helper function to call an arbitrary runtime API using a `RelayChainInterface` client.
/// Unlike the trait method, this function can be generic, so it handles the encoding of input and
/// output params.
pub async fn call_runtime_api<R>(
client: &(impl RelayChainInterface + ?Sized),
method_name: &'static str,
hash: RelayHash,
payload: impl Encode,
) -> RelayChainResult<R>
where
R: Decode,
{
let res = client.call_runtime_api(method_name, hash, &payload.encode()).await?;
Decode::decode(&mut &*res).map_err(Into::into)
}
11 changes: 7 additions & 4 deletions cumulus/client/relay-chain-minimal-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,20 @@ async fn build_interface(
client: RelayChainRpcClient,
) -> RelayChainResult<(Arc<(dyn RelayChainInterface + 'static)>, Option<CollatorPair>)> {
let collator_pair = CollatorPair::generate().0;
let blockchain_rpc_client = Arc::new(BlockChainRpcClient::new(client.clone()));
let collator_node = match polkadot_config.network.network_backend {
sc_network::config::NetworkBackendType::Libp2p =>
new_minimal_relay_chain::<RelayBlock, sc_network::NetworkWorker<RelayBlock, RelayHash>>(
polkadot_config,
collator_pair.clone(),
Arc::new(BlockChainRpcClient::new(client.clone())),
blockchain_rpc_client,
)
.await?,
sc_network::config::NetworkBackendType::Litep2p =>
new_minimal_relay_chain::<RelayBlock, sc_network::Litep2pNetworkBackend>(
polkadot_config,
collator_pair.clone(),
Arc::new(BlockChainRpcClient::new(client.clone())),
blockchain_rpc_client,
)
.await?,
};
Expand All @@ -120,17 +121,19 @@ async fn build_interface(
}

pub async fn build_minimal_relay_chain_node_with_rpc(
polkadot_config: Configuration,
relay_chain_config: Configuration,
parachain_prometheus_registry: Option<&Registry>,
task_manager: &mut TaskManager,
relay_chain_url: Vec<Url>,
) -> RelayChainResult<(Arc<(dyn RelayChainInterface + 'static)>, Option<CollatorPair>)> {
let client = cumulus_relay_chain_rpc_interface::create_client_and_start_worker(
relay_chain_url,
task_manager,
parachain_prometheus_registry,
)
.await?;

build_interface(polkadot_config, task_manager, client).await
build_interface(relay_chain_config, task_manager, client).await
}

pub async fn build_minimal_relay_chain_node_light_client(
Expand Down
2 changes: 2 additions & 0 deletions cumulus/client/relay-chain-rpc-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ sp-version = { workspace = true, default-features = true }
sc-client-api = { workspace = true, default-features = true }
sc-rpc-api = { workspace = true, default-features = true }
sc-service = { workspace = true, default-features = true }
prometheus-endpoint = { workspace = true, default-features = true }

tokio = { features = ["sync"], workspace = true, default-features = true }
tokio-util = { features = ["compat"], workspace = true }
Expand All @@ -49,3 +50,4 @@ either = { workspace = true, default-features = true }
thiserror = { workspace = true }
rand = { workspace = true, default-features = true }
pin-project = { workspace = true }
prometheus = { workspace = true }
18 changes: 16 additions & 2 deletions cumulus/client/relay-chain-rpc-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use cumulus_primitives_core::relay_chain::BlockId;
pub use url::Url;

mod light_client_worker;
mod metrics;
mod reconnecting_ws_client;
mod rpc_client;
mod tokio_platform;
Expand Down Expand Up @@ -87,12 +88,13 @@ impl RelayChainInterface for RelayChainRpcInterface {
async fn header(&self, block_id: BlockId) -> RelayChainResult<Option<PHeader>> {
let hash = match block_id {
BlockId::Hash(hash) => hash,
BlockId::Number(num) =>
BlockId::Number(num) => {
if let Some(hash) = self.rpc_client.chain_get_block_hash(Some(num)).await? {
hash
} else {
return Ok(None)
},
}
},
};
let header = self.rpc_client.chain_get_header(Some(hash)).await?;

Expand Down Expand Up @@ -163,6 +165,18 @@ impl RelayChainInterface for RelayChainRpcInterface {
self.rpc_client.chain_get_finalized_head().await
}

async fn call_runtime_api(
&self,
method_name: &'static str,
hash: RelayHash,
payload: &[u8],
) -> RelayChainResult<Vec<u8>> {
self.rpc_client
.call_remote_runtime_function_encoded(method_name, hash, payload)
.await
.map(|bytes| bytes.to_vec())
}

async fn is_major_syncing(&self) -> RelayChainResult<bool> {
self.rpc_client.system_health().await.map(|h| h.is_syncing)
}
Expand Down
49 changes: 49 additions & 0 deletions cumulus/client/relay-chain-rpc-interface/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.

// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

use prometheus::{Error as PrometheusError, HistogramTimer, Registry};
use prometheus_endpoint::{HistogramOpts, HistogramVec, Opts};

/// Gathers metrics about the blockchain RPC client.
#[derive(Clone)]
pub(crate) struct RelaychainRpcMetrics {
rpc_request: HistogramVec,
}

impl RelaychainRpcMetrics {
pub(crate) fn register(registry: &Registry) -> Result<Self, PrometheusError> {
Ok(Self {
rpc_request: prometheus_endpoint::register(
HistogramVec::new(
HistogramOpts {
common_opts: Opts::new(
"relay_chain_rpc_interface",
"Tracks stats about cumulus relay chain RPC interface",
),
buckets: prometheus::exponential_buckets(0.001, 4.0, 9)
.expect("function parameters are constant and always valid; qed"),
},
&["method"],
)?,
registry,
)?,
})
}

pub(crate) fn start_request_timer(&self, method: &str) -> HistogramTimer {
self.rpc_request.with_label_values(&[method]).start_timer()
}
}
Loading

0 comments on commit d366111

Please sign in to comment.