mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Introduce async runtime calling trait for runtime-api subsystem (#5782)
* Implement OverseerRuntimeClient * blockchainevents * Update patches * Finish merging rntime-api subsystem * First version that is able to produce blocks * Make OverseerRuntimeClient async * Move overseer notification stream forwarding to cumulus * Remove unused imports * Add more logging to collator-protocol * Lockfile * Use hashes in OverseerRuntimeClient * Move OverseerRuntimeClient into extra module * Fix old session info call and make HeadSupportsParachain async * Improve naming of trait * Cleanup * Remove unused From trait implementation * Remove unwanted debug print * Move trait to polkadot-node-subsystem-types * Add sections to runtime client Co-authored-by: Davide Galassi <davxy@datawok.net> * Reorder methods * Fix spelling * Fix spacing in Cargo.toml Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Remove unused babe methods Co-authored-by: Davide Galassi <davxy@datawok.net> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Generated
+9
-2
@@ -327,9 +327,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.53"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
|
||||
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -6295,6 +6295,7 @@ name = "polkadot-node-core-approval-voting"
|
||||
version = "0.9.26"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"async-trait",
|
||||
"bitvec",
|
||||
"derive_more",
|
||||
"futures",
|
||||
@@ -6590,6 +6591,7 @@ dependencies = [
|
||||
"polkadot-node-primitives",
|
||||
"polkadot-node-subsystem",
|
||||
"polkadot-node-subsystem-test-helpers",
|
||||
"polkadot-node-subsystem-types",
|
||||
"polkadot-node-subsystem-util",
|
||||
"polkadot-primitives",
|
||||
"polkadot-primitives-test-helpers",
|
||||
@@ -6720,6 +6722,7 @@ dependencies = [
|
||||
name = "polkadot-node-subsystem-types"
|
||||
version = "0.9.26"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"derive_more",
|
||||
"futures",
|
||||
"orchestra",
|
||||
@@ -6730,6 +6733,9 @@ dependencies = [
|
||||
"polkadot-statement-table",
|
||||
"sc-network",
|
||||
"smallvec",
|
||||
"sp-api",
|
||||
"sp-authority-discovery",
|
||||
"sp-consensus-babe",
|
||||
"substrate-prometheus-endpoint",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -6779,6 +6785,7 @@ name = "polkadot-overseer"
|
||||
version = "0.9.26"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"async-trait",
|
||||
"femme",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
|
||||
@@ -31,6 +31,7 @@ sp-application-crypto = { git = "https://github.com/paritytech/substrate", branc
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
async-trait = "0.1.56"
|
||||
parking_lot = "0.12.0"
|
||||
rand_core = "0.5.1" # should match schnorrkel
|
||||
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
@@ -38,6 +38,7 @@ use polkadot_primitives::v2::{
|
||||
use std::time::Duration;
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use async_trait::async_trait;
|
||||
use parking_lot::Mutex;
|
||||
use sp_keyring::sr25519::Keyring as Sr25519Keyring;
|
||||
use sp_keystore::CryptoStore;
|
||||
@@ -117,8 +118,9 @@ pub mod test_constants {
|
||||
|
||||
struct MockSupportsParachains;
|
||||
|
||||
#[async_trait]
|
||||
impl HeadSupportsParachains for MockSupportsParachains {
|
||||
fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
async fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,16 @@ gum = { package = "tracing-gum", path = "../../gum" }
|
||||
memory-lru = "0.1.0"
|
||||
parity-util-mem = { version = "0.11.0", default-features = false }
|
||||
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
polkadot-primitives = { path = "../../../primitives" }
|
||||
polkadot-node-subsystem = {path = "../../subsystem" }
|
||||
polkadot-node-subsystem = { path = "../../subsystem" }
|
||||
polkadot-node-subsystem-types = { path = "../../subsystem-types" }
|
||||
polkadot-node-subsystem-util = { path = "../../subsystem-util" }
|
||||
|
||||
[dev-dependencies]
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
futures = { version = "0.3.21", features = ["thread-pool"] }
|
||||
|
||||
@@ -27,14 +27,8 @@ use polkadot_node_subsystem::{
|
||||
messages::{RuntimeApiMessage, RuntimeApiRequest as Request},
|
||||
overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult,
|
||||
};
|
||||
use polkadot_primitives::{
|
||||
runtime_api::ParachainHost,
|
||||
v2::{Block, BlockId, Hash},
|
||||
};
|
||||
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_authority_discovery::AuthorityDiscoveryApi;
|
||||
use sp_consensus_babe::BabeApi;
|
||||
use polkadot_node_subsystem_types::RuntimeApiSubsystemClient;
|
||||
use polkadot_primitives::v2::Hash;
|
||||
|
||||
use cache::{RequestResult, RequestResultCache};
|
||||
use futures::{channel::oneshot, prelude::*, select, stream::FuturesUnordered};
|
||||
@@ -88,8 +82,7 @@ impl<Client> RuntimeApiSubsystem<Client> {
|
||||
#[overseer::subsystem(RuntimeApi, error = SubsystemError, prefix = self::overseer)]
|
||||
impl<Client, Context> RuntimeApiSubsystem<Client>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block> + Send + 'static + Sync,
|
||||
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
Client: RuntimeApiSubsystemClient + Send + Sync + 'static,
|
||||
{
|
||||
fn start(self, ctx: Context) -> SpawnedSubsystem {
|
||||
SpawnedSubsystem { future: run(ctx, self).boxed(), name: "runtime-api-subsystem" }
|
||||
@@ -98,8 +91,7 @@ where
|
||||
|
||||
impl<Client> RuntimeApiSubsystem<Client>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block> + Send + 'static + Sync,
|
||||
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
Client: RuntimeApiSubsystemClient + Send + 'static + Sync,
|
||||
{
|
||||
fn store_cache(&mut self, result: RequestResult) {
|
||||
use RequestResult::*;
|
||||
@@ -282,7 +274,7 @@ where
|
||||
};
|
||||
|
||||
let request = async move {
|
||||
let result = make_runtime_api_request(client, metrics, relay_parent, request);
|
||||
let result = make_runtime_api_request(client, metrics, relay_parent, request).await;
|
||||
let _ = sender.send(result);
|
||||
}
|
||||
.boxed();
|
||||
@@ -317,8 +309,7 @@ async fn run<Client, Context>(
|
||||
mut subsystem: RuntimeApiSubsystem<Client>,
|
||||
) -> SubsystemResult<()>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
|
||||
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
Client: RuntimeApiSubsystemClient + Send + Sync + 'static,
|
||||
{
|
||||
loop {
|
||||
// Let's add some back pressure when the subsystem is running at `MAX_PARALLEL_REQUESTS`.
|
||||
@@ -348,26 +339,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn make_runtime_api_request<Client>(
|
||||
async fn make_runtime_api_request<Client>(
|
||||
client: Arc<Client>,
|
||||
metrics: Metrics,
|
||||
relay_parent: Hash,
|
||||
request: Request,
|
||||
) -> Option<RequestResult>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block>,
|
||||
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
Client: RuntimeApiSubsystemClient + 'static,
|
||||
{
|
||||
use sp_api::ApiExt;
|
||||
|
||||
let _timer = metrics.time_make_runtime_api_request();
|
||||
|
||||
macro_rules! query {
|
||||
($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:literal, $sender:expr) => {{
|
||||
let sender = $sender;
|
||||
let api = client.runtime_api();
|
||||
|
||||
let runtime_version = api.api_version::<dyn ParachainHost<Block>>(&BlockId::Hash(relay_parent))
|
||||
let runtime_version = client.api_version_parachain_host(relay_parent).await
|
||||
.unwrap_or_else(|e| {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -385,7 +371,7 @@ where
|
||||
});
|
||||
|
||||
let res = if runtime_version >= $version {
|
||||
api.$api_name(&BlockId::Hash(relay_parent) $(, $param.clone() )*)
|
||||
client.$api_name(relay_parent $(, $param.clone() )*).await
|
||||
.map_err(|e| RuntimeApiError::Execution {
|
||||
runtime_api_name: stringify!($api_name),
|
||||
source: std::sync::Arc::new(e),
|
||||
@@ -404,11 +390,7 @@ where
|
||||
|
||||
match request {
|
||||
Request::Version(sender) => {
|
||||
let api = client.runtime_api();
|
||||
|
||||
let runtime_version = match api
|
||||
.api_version::<dyn ParachainHost<Block>>(&BlockId::Hash(relay_parent))
|
||||
{
|
||||
let runtime_version = match client.api_version_parachain_host(relay_parent).await {
|
||||
Ok(Some(v)) => Ok(v),
|
||||
Ok(None) => Err(RuntimeApiError::NotSupported { runtime_api_name: "api_version" }),
|
||||
Err(e) => Err(RuntimeApiError::Execution {
|
||||
@@ -465,25 +447,24 @@ where
|
||||
Request::CandidateEvents(sender) =>
|
||||
query!(CandidateEvents, candidate_events(), ver = 1, sender),
|
||||
Request::SessionInfo(index, sender) => {
|
||||
let api = client.runtime_api();
|
||||
let block_id = BlockId::Hash(relay_parent);
|
||||
|
||||
let api_version = api
|
||||
.api_version::<dyn ParachainHost<Block>>(&BlockId::Hash(relay_parent))
|
||||
let api_version = client
|
||||
.api_version_parachain_host(relay_parent)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default();
|
||||
|
||||
let res = if api_version >= 2 {
|
||||
let res =
|
||||
api.session_info(&block_id, index).map_err(|e| RuntimeApiError::Execution {
|
||||
let res = client.session_info(relay_parent, index).await.map_err(|e| {
|
||||
RuntimeApiError::Execution {
|
||||
runtime_api_name: "SessionInfo",
|
||||
source: std::sync::Arc::new(e),
|
||||
});
|
||||
}
|
||||
});
|
||||
metrics.on_request(res.is_ok());
|
||||
res
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
let res = api.session_info_before_version_2(&block_id, index).map_err(|e| {
|
||||
let res = client.session_info_before_version_2(relay_parent, index).await.map_err(|e| {
|
||||
RuntimeApiError::Execution {
|
||||
runtime_api_name: "SessionInfo",
|
||||
source: std::sync::Arc::new(e),
|
||||
|
||||
@@ -20,13 +20,19 @@ use ::test_helpers::{dummy_committed_candidate_receipt, dummy_validation_code};
|
||||
use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfiguration};
|
||||
use polkadot_node_subsystem::SpawnGlue;
|
||||
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
|
||||
use polkadot_primitives::v2::{
|
||||
AuthorityDiscoveryId, BlockNumber, CandidateEvent, CandidateHash, CommittedCandidateReceipt,
|
||||
CoreState, DisputeState, GroupRotationInfo, Id as ParaId, InboundDownwardMessage,
|
||||
InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
|
||||
ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash,
|
||||
ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
use polkadot_primitives::{
|
||||
runtime_api::ParachainHost,
|
||||
v2::{
|
||||
AuthorityDiscoveryId, Block, BlockNumber, CandidateEvent, CandidateHash,
|
||||
CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Id as ParaId,
|
||||
InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption,
|
||||
PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo,
|
||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
},
|
||||
};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_authority_discovery::AuthorityDiscoveryApi;
|
||||
use sp_consensus_babe::BabeApi;
|
||||
use sp_core::testing::TaskExecutor;
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
|
||||
@@ -20,6 +20,7 @@ gum = { package = "tracing-gum", path = "../gum" }
|
||||
lru = "0.7"
|
||||
parity-util-mem = { version = "0.11.0", default-features = false }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
async-trait = "0.1.56"
|
||||
|
||||
[dev-dependencies]
|
||||
metered = { package = "prioritized-metered-channel", path = "../metered-channel" }
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
use futures::{channel::oneshot, pending, pin_mut, select, stream, FutureExt, StreamExt};
|
||||
use futures_timer::Delay;
|
||||
use orchestra::async_trait;
|
||||
use std::time::Duration;
|
||||
|
||||
use ::test_helpers::{dummy_candidate_descriptor, dummy_hash};
|
||||
@@ -34,8 +35,10 @@ use polkadot_overseer::{
|
||||
use polkadot_primitives::v2::{CandidateReceipt, Hash};
|
||||
|
||||
struct AlwaysSupportsParachains;
|
||||
|
||||
#[async_trait]
|
||||
impl HeadSupportsParachains for AlwaysSupportsParachains {
|
||||
fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
async fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +71,7 @@ use futures::{channel::oneshot, future::BoxFuture, select, Future, FutureExt, St
|
||||
use lru::LruCache;
|
||||
|
||||
use client::{BlockImportNotification, BlockchainEvents, FinalityNotification};
|
||||
use polkadot_primitives::{
|
||||
runtime_api::ParachainHost,
|
||||
v2::{Block, BlockId, BlockNumber, Hash},
|
||||
};
|
||||
use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use polkadot_primitives::v2::{Block, BlockNumber, Hash};
|
||||
|
||||
use polkadot_node_subsystem_types::messages::{
|
||||
ApprovalDistributionMessage, ApprovalVotingMessage, AvailabilityDistributionMessage,
|
||||
@@ -89,6 +85,7 @@ use polkadot_node_subsystem_types::messages::{
|
||||
pub use polkadot_node_subsystem_types::{
|
||||
errors::{SubsystemError, SubsystemResult},
|
||||
jaeger, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, OverseerSignal,
|
||||
RuntimeApiSubsystemClient,
|
||||
};
|
||||
|
||||
pub mod metrics;
|
||||
@@ -157,25 +154,20 @@ impl<S: SpawnNamed + Clone + Send + Sync> crate::gen::Spawner for SpawnGlue<S> {
|
||||
}
|
||||
|
||||
/// Whether a header supports parachain consensus or not.
|
||||
#[async_trait::async_trait]
|
||||
pub trait HeadSupportsParachains {
|
||||
/// Return true if the given header supports parachain consensus. Otherwise, false.
|
||||
fn head_supports_parachains(&self, head: &Hash) -> bool;
|
||||
async fn head_supports_parachains(&self, head: &Hash) -> bool;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<Client> HeadSupportsParachains for Arc<Client>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block>,
|
||||
Client::Api: ParachainHost<Block>,
|
||||
Client: RuntimeApiSubsystemClient + Sync + Send,
|
||||
{
|
||||
fn head_supports_parachains(&self, head: &Hash) -> bool {
|
||||
let id = BlockId::Hash(*head);
|
||||
async fn head_supports_parachains(&self, head: &Hash) -> bool {
|
||||
// Check that the `ParachainHost` runtime api is at least with version 1 present on chain.
|
||||
self.runtime_api()
|
||||
.api_version::<dyn ParachainHost<Block>>(&id)
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(0) >=
|
||||
1
|
||||
self.api_version_parachain_host(*head).await.ok().flatten().unwrap_or(0) >= 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,9 +413,12 @@ pub async fn forward_events<P: BlockchainEvents<Block>>(client: Arc<P>, mut hand
|
||||
/// # fn main() { executor::block_on(async move {
|
||||
///
|
||||
/// struct AlwaysSupportsParachains;
|
||||
///
|
||||
/// #[async_trait::async_trait]
|
||||
/// impl HeadSupportsParachains for AlwaysSupportsParachains {
|
||||
/// fn head_supports_parachains(&self, _head: &Hash) -> bool { true }
|
||||
/// async fn head_supports_parachains(&self, _head: &Hash) -> bool { true }
|
||||
/// }
|
||||
///
|
||||
/// let spawner = sp_core::testing::TaskExecutor::new();
|
||||
/// let (overseer, _handle) = dummy_overseer_builder(spawner, AlwaysSupportsParachains, None)
|
||||
/// .unwrap()
|
||||
@@ -718,7 +713,7 @@ where
|
||||
// Notify about active leaves on startup before starting the loop
|
||||
for (hash, number) in std::mem::take(&mut self.leaves) {
|
||||
let _ = self.active_leaves.insert(hash, number);
|
||||
if let Some((span, status)) = self.on_head_activated(&hash, None) {
|
||||
if let Some((span, status)) = self.on_head_activated(&hash, None).await {
|
||||
let update =
|
||||
ActiveLeavesUpdate::start_work(ActivatedLeaf { hash, number, status, span });
|
||||
self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await?;
|
||||
@@ -780,7 +775,7 @@ where
|
||||
},
|
||||
};
|
||||
|
||||
let mut update = match self.on_head_activated(&block.hash, Some(block.parent_hash)) {
|
||||
let mut update = match self.on_head_activated(&block.hash, Some(block.parent_hash)).await {
|
||||
Some((span, status)) => ActiveLeavesUpdate::start_work(ActivatedLeaf {
|
||||
hash: block.hash,
|
||||
number: block.number,
|
||||
@@ -837,12 +832,12 @@ where
|
||||
|
||||
/// Handles a header activation. If the header's state doesn't support the parachains API,
|
||||
/// this returns `None`.
|
||||
fn on_head_activated(
|
||||
async fn on_head_activated(
|
||||
&mut self,
|
||||
hash: &Hash,
|
||||
parent_hash: Option<Hash>,
|
||||
) -> Option<(Arc<jaeger::Span>, LeafStatus)> {
|
||||
if !self.supports_parachains.head_supports_parachains(hash) {
|
||||
if !self.supports_parachains.head_supports_parachains(hash).await {
|
||||
return None
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use futures::{executor, pending, pin_mut, poll, select, stream, FutureExt};
|
||||
use std::{collections::HashMap, sync::atomic, task::Poll};
|
||||
|
||||
@@ -154,8 +155,9 @@ where
|
||||
|
||||
struct MockSupportsParachains;
|
||||
|
||||
#[async_trait]
|
||||
impl HeadSupportsParachains for MockSupportsParachains {
|
||||
fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
async fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,8 +401,10 @@ mod tests {
|
||||
use sp_core::traits::SpawnNamed;
|
||||
|
||||
struct AlwaysSupportsParachains;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl HeadSupportsParachains for AlwaysSupportsParachains {
|
||||
fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
async fn head_supports_parachains(&self, _head: &Hash) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ polkadot-statement-table = { path = "../../statement-table" }
|
||||
polkadot-node-jaeger = { path = "../jaeger" }
|
||||
orchestra = { path = "../orchestra" }
|
||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
smallvec = "1.8.0"
|
||||
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
thiserror = "1.0.31"
|
||||
async-trait = "0.1.56"
|
||||
|
||||
@@ -30,6 +30,9 @@ use smallvec::SmallVec;
|
||||
pub mod errors;
|
||||
pub mod messages;
|
||||
|
||||
mod runtime_client;
|
||||
pub use runtime_client::RuntimeApiSubsystemClient;
|
||||
|
||||
pub use jaeger::*;
|
||||
pub use polkadot_node_jaeger as jaeger;
|
||||
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
// Copyright 2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot 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.
|
||||
|
||||
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use polkadot_primitives::{
|
||||
runtime_api::ParachainHost,
|
||||
v2::{
|
||||
Block, BlockId, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
|
||||
CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id,
|
||||
InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption,
|
||||
PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo,
|
||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
},
|
||||
};
|
||||
use sp_api::{ApiError, ApiExt, ProvideRuntimeApi};
|
||||
use sp_authority_discovery::AuthorityDiscoveryApi;
|
||||
use sp_consensus_babe::{BabeApi, Epoch};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Exposes all runtime calls that are used by the runtime API subsystem.
|
||||
#[async_trait]
|
||||
pub trait RuntimeApiSubsystemClient {
|
||||
/// Parachain host API version
|
||||
async fn api_version_parachain_host(&self, at: Hash) -> Result<Option<u32>, ApiError>;
|
||||
|
||||
// === ParachainHost API ===
|
||||
|
||||
/// Get the current validators.
|
||||
async fn validators(&self, at: Hash) -> Result<Vec<ValidatorId>, ApiError>;
|
||||
|
||||
/// Returns the validator groups and rotation info localized based on the hypothetical child
|
||||
/// of a block whose state this is invoked on. Note that `now` in the `GroupRotationInfo`
|
||||
/// should be the successor of the number of the block.
|
||||
async fn validator_groups(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>), ApiError>;
|
||||
|
||||
/// Yields information on all availability cores as relevant to the child block.
|
||||
/// Cores are either free or occupied. Free cores can have paras assigned to them.
|
||||
async fn availability_cores(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<CoreState<Hash, BlockNumber>>, ApiError>;
|
||||
|
||||
/// Yields the persisted validation data for the given `ParaId` along with an assumption that
|
||||
/// should be used if the para currently occupies a core.
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
async fn persisted_validation_data(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<PersistedValidationData<Hash, BlockNumber>>, ApiError>;
|
||||
|
||||
/// Returns the persisted validation data for the given `ParaId` along with the corresponding
|
||||
/// validation code hash. Instead of accepting assumption about the para, matches the validation
|
||||
/// data hash against an expected one and yields `None` if they're not equal.
|
||||
async fn assumed_validation_data(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
expected_persisted_validation_data_hash: Hash,
|
||||
) -> Result<Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)>, ApiError>;
|
||||
|
||||
/// Checks if the given validation outputs pass the acceptance criteria.
|
||||
async fn check_validation_outputs(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
outputs: CandidateCommitments,
|
||||
) -> Result<bool, ApiError>;
|
||||
|
||||
/// Returns the session index expected at a child of the block.
|
||||
///
|
||||
/// This can be used to instantiate a `SigningContext`.
|
||||
async fn session_index_for_child(&self, at: Hash) -> Result<SessionIndex, ApiError>;
|
||||
|
||||
/// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`.
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
async fn validation_code(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCode>, ApiError>;
|
||||
|
||||
/// Get the receipt of a candidate pending availability. This returns `Some` for any paras
|
||||
/// assigned to occupied cores in `availability_cores` and `None` otherwise.
|
||||
async fn candidate_pending_availability(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<CommittedCandidateReceipt<Hash>>, ApiError>;
|
||||
|
||||
/// Get a vector of events concerning candidates that occurred within a block.
|
||||
async fn candidate_events(&self, at: Hash) -> Result<Vec<CandidateEvent<Hash>>, ApiError>;
|
||||
|
||||
/// Get all the pending inbound messages in the downward message queue for a para.
|
||||
async fn dmq_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<Vec<InboundDownwardMessage<BlockNumber>>, ApiError>;
|
||||
|
||||
/// Get the contents of all channels addressed to the given recipient. Channels that have no
|
||||
/// messages in them are also included.
|
||||
async fn inbound_hrmp_channels_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<BTreeMap<Id, Vec<InboundHrmpMessage<BlockNumber>>>, ApiError>;
|
||||
|
||||
/// Get the validation code from its hash.
|
||||
async fn validation_code_by_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
hash: ValidationCodeHash,
|
||||
) -> Result<Option<ValidationCode>, ApiError>;
|
||||
|
||||
/// Scrape dispute relevant from on-chain, backing votes and resolved disputes.
|
||||
async fn on_chain_votes(&self, at: Hash)
|
||||
-> Result<Option<ScrapedOnChainVotes<Hash>>, ApiError>;
|
||||
|
||||
/***** Added in v2 *****/
|
||||
|
||||
/// Get the session info for the given session, if stored.
|
||||
///
|
||||
/// NOTE: This function is only available since parachain host version 2.
|
||||
async fn session_info(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<SessionInfo>, ApiError>;
|
||||
|
||||
/// Get the session info for the given session, if stored.
|
||||
///
|
||||
/// NOTE: This function is only available since parachain host version 2.
|
||||
async fn session_info_before_version_2(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<polkadot_primitives::v2::OldV1SessionInfo>, ApiError>;
|
||||
|
||||
/// Submits a PVF pre-checking statement into the transaction pool.
|
||||
///
|
||||
/// NOTE: This function is only available since parachain host version 2.
|
||||
async fn submit_pvf_check_statement(
|
||||
&self,
|
||||
at: Hash,
|
||||
stmt: PvfCheckStatement,
|
||||
signature: ValidatorSignature,
|
||||
) -> Result<(), ApiError>;
|
||||
|
||||
/// Returns code hashes of PVFs that require pre-checking by validators in the active set.
|
||||
///
|
||||
/// NOTE: This function is only available since parachain host version 2.
|
||||
async fn pvfs_require_precheck(&self, at: Hash) -> Result<Vec<ValidationCodeHash>, ApiError>;
|
||||
|
||||
/// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`.
|
||||
///
|
||||
/// NOTE: This function is only available since parachain host version 2.
|
||||
async fn validation_code_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCodeHash>, ApiError>;
|
||||
|
||||
/// Returns all onchain disputes.
|
||||
/// This is a staging method! Do not use on production runtimes!
|
||||
async fn staging_get_disputes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError>;
|
||||
|
||||
// === BABE API ===
|
||||
|
||||
/// Returns information regarding the current epoch.
|
||||
async fn current_epoch(&self, at: Hash) -> Result<Epoch, ApiError>;
|
||||
|
||||
// === AuthorityDiscovery API ===
|
||||
|
||||
/// Retrieve authority identifiers of the current and next authority set.
|
||||
async fn authorities(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> std::result::Result<Vec<sp_authority_discovery::AuthorityId>, ApiError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T> RuntimeApiSubsystemClient for T
|
||||
where
|
||||
T: ProvideRuntimeApi<Block> + Send + Sync,
|
||||
T::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
{
|
||||
async fn validators(&self, at: Hash) -> Result<Vec<ValidatorId>, ApiError> {
|
||||
self.runtime_api().validators(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn validator_groups(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>), ApiError> {
|
||||
self.runtime_api().validator_groups(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn availability_cores(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<CoreState<Hash, BlockNumber>>, ApiError> {
|
||||
self.runtime_api().availability_cores(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn persisted_validation_data(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<PersistedValidationData<Hash, BlockNumber>>, ApiError> {
|
||||
self.runtime_api()
|
||||
.persisted_validation_data(&BlockId::Hash(at), para_id, assumption)
|
||||
}
|
||||
|
||||
async fn assumed_validation_data(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
expected_persisted_validation_data_hash: Hash,
|
||||
) -> Result<Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)>, ApiError>
|
||||
{
|
||||
self.runtime_api().assumed_validation_data(
|
||||
&BlockId::Hash(at),
|
||||
para_id,
|
||||
expected_persisted_validation_data_hash,
|
||||
)
|
||||
}
|
||||
|
||||
async fn check_validation_outputs(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
outputs: CandidateCommitments,
|
||||
) -> Result<bool, ApiError> {
|
||||
self.runtime_api()
|
||||
.check_validation_outputs(&BlockId::Hash(at), para_id, outputs)
|
||||
}
|
||||
|
||||
async fn session_index_for_child(&self, at: Hash) -> Result<SessionIndex, ApiError> {
|
||||
self.runtime_api().session_index_for_child(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn validation_code(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCode>, ApiError> {
|
||||
self.runtime_api().validation_code(&BlockId::Hash(at), para_id, assumption)
|
||||
}
|
||||
|
||||
async fn candidate_pending_availability(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<CommittedCandidateReceipt<Hash>>, ApiError> {
|
||||
self.runtime_api().candidate_pending_availability(&BlockId::Hash(at), para_id)
|
||||
}
|
||||
|
||||
async fn candidate_events(&self, at: Hash) -> Result<Vec<CandidateEvent<Hash>>, ApiError> {
|
||||
self.runtime_api().candidate_events(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn dmq_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<Vec<InboundDownwardMessage<BlockNumber>>, ApiError> {
|
||||
self.runtime_api().dmq_contents(&BlockId::Hash(at), recipient)
|
||||
}
|
||||
|
||||
async fn inbound_hrmp_channels_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<BTreeMap<Id, Vec<InboundHrmpMessage<BlockNumber>>>, ApiError> {
|
||||
self.runtime_api().inbound_hrmp_channels_contents(&BlockId::Hash(at), recipient)
|
||||
}
|
||||
|
||||
async fn validation_code_by_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
hash: ValidationCodeHash,
|
||||
) -> Result<Option<ValidationCode>, ApiError> {
|
||||
self.runtime_api().validation_code_by_hash(&BlockId::Hash(at), hash)
|
||||
}
|
||||
|
||||
async fn on_chain_votes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Option<ScrapedOnChainVotes<Hash>>, ApiError> {
|
||||
self.runtime_api().on_chain_votes(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn session_info(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<SessionInfo>, ApiError> {
|
||||
self.runtime_api().session_info(&BlockId::Hash(at), index)
|
||||
}
|
||||
|
||||
async fn submit_pvf_check_statement(
|
||||
&self,
|
||||
at: Hash,
|
||||
stmt: PvfCheckStatement,
|
||||
signature: ValidatorSignature,
|
||||
) -> Result<(), ApiError> {
|
||||
self.runtime_api()
|
||||
.submit_pvf_check_statement(&BlockId::Hash(at), stmt, signature)
|
||||
}
|
||||
|
||||
async fn pvfs_require_precheck(&self, at: Hash) -> Result<Vec<ValidationCodeHash>, ApiError> {
|
||||
self.runtime_api().pvfs_require_precheck(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn validation_code_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCodeHash>, ApiError> {
|
||||
self.runtime_api().validation_code_hash(&BlockId::Hash(at), para_id, assumption)
|
||||
}
|
||||
|
||||
async fn current_epoch(&self, at: Hash) -> Result<Epoch, ApiError> {
|
||||
self.runtime_api().current_epoch(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn authorities(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> std::result::Result<Vec<sp_authority_discovery::AuthorityId>, ApiError> {
|
||||
self.runtime_api().authorities(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
async fn api_version_parachain_host(&self, at: Hash) -> Result<Option<u32>, ApiError> {
|
||||
self.runtime_api().api_version::<dyn ParachainHost<Block>>(&BlockId::Hash(at))
|
||||
}
|
||||
|
||||
#[warn(deprecated)]
|
||||
async fn session_info_before_version_2(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<polkadot_primitives::v2::OldV1SessionInfo>, ApiError> {
|
||||
#[allow(deprecated)]
|
||||
self.runtime_api().session_info_before_version_2(&BlockId::Hash(at), index)
|
||||
}
|
||||
|
||||
async fn staging_get_disputes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
|
||||
self.runtime_api().staging_get_disputes(&BlockId::Hash(at))
|
||||
}
|
||||
}
|
||||
@@ -21,3 +21,4 @@ use_field_init_shorthand = true
|
||||
ignore = [
|
||||
"bridges",
|
||||
]
|
||||
edition = "2021"
|
||||
|
||||
Reference in New Issue
Block a user