diff --git a/Cargo.lock b/Cargo.lock index 50e765016390..4a2da99419d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/node/core/approval-voting/Cargo.toml b/node/core/approval-voting/Cargo.toml index 646817a5aa4e..79f78bba7f61 100644 --- a/node/core/approval-voting/Cargo.toml +++ b/node/core/approval-voting/Cargo.toml @@ -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" } diff --git a/node/core/approval-voting/src/tests.rs b/node/core/approval-voting/src/tests.rs index 25dcfcdb4e81..641e6cb3a4f9 100644 --- a/node/core/approval-voting/src/tests.rs +++ b/node/core/approval-voting/src/tests.rs @@ -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 } } diff --git a/node/core/runtime-api/Cargo.toml b/node/core/runtime-api/Cargo.toml index 3af58ab5d2a0..bf14836b9b1b 100644 --- a/node/core/runtime-api/Cargo.toml +++ b/node/core/runtime-api/Cargo.toml @@ -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"] } diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 691ca9e655d9..a815b76a8d7c 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -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 RuntimeApiSubsystem { #[overseer::subsystem(RuntimeApi, error = SubsystemError, prefix = self::overseer)] impl RuntimeApiSubsystem where - Client: ProvideRuntimeApi + Send + 'static + Sync, - Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + 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 RuntimeApiSubsystem where - Client: ProvideRuntimeApi + Send + 'static + Sync, - Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + 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( mut subsystem: RuntimeApiSubsystem, ) -> SubsystemResult<()> where - Client: ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + 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( +async fn make_runtime_api_request( client: Arc, metrics: Metrics, relay_parent: Hash, request: Request, ) -> Option where - Client: ProvideRuntimeApi, - Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + 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::>(&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::>(&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::>(&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), diff --git a/node/core/runtime-api/src/tests.rs b/node/core/runtime-api/src/tests.rs index fdcd66ecf2a7..b1a1bba73769 100644 --- a/node/core/runtime-api/src/tests.rs +++ b/node/core/runtime-api/src/tests.rs @@ -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}, diff --git a/node/overseer/Cargo.toml b/node/overseer/Cargo.toml index 8341d14f9251..c586f748f95a 100644 --- a/node/overseer/Cargo.toml +++ b/node/overseer/Cargo.toml @@ -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" } diff --git a/node/overseer/examples/minimal-example.rs b/node/overseer/examples/minimal-example.rs index 6033815ddd50..be6779819eb7 100644 --- a/node/overseer/examples/minimal-example.rs +++ b/node/overseer/examples/minimal-example.rs @@ -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 } } diff --git a/node/overseer/src/lib.rs b/node/overseer/src/lib.rs index fefcc4dba0ce..43386352b77a 100644 --- a/node/overseer/src/lib.rs +++ b/node/overseer/src/lib.rs @@ -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 crate::gen::Spawner for SpawnGlue { } /// 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 HeadSupportsParachains for Arc where - Client: ProvideRuntimeApi, - Client::Api: ParachainHost, + 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::>(&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>(client: Arc

, 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, ) -> Option<(Arc, LeafStatus)> { - if !self.supports_parachains.head_supports_parachains(hash) { + if !self.supports_parachains.head_supports_parachains(hash).await { return None } diff --git a/node/overseer/src/tests.rs b/node/overseer/src/tests.rs index 25a6d07e3934..121c707c2541 100644 --- a/node/overseer/src/tests.rs +++ b/node/overseer/src/tests.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +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 } } diff --git a/node/subsystem-test-helpers/src/lib.rs b/node/subsystem-test-helpers/src/lib.rs index cc263266366e..e2e61c2006d8 100644 --- a/node/subsystem-test-helpers/src/lib.rs +++ b/node/subsystem-test-helpers/src/lib.rs @@ -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 } } diff --git a/node/subsystem-types/Cargo.toml b/node/subsystem-types/Cargo.toml index 2e17acf6ff7b..9a646d81965c 100644 --- a/node/subsystem-types/Cargo.toml +++ b/node/subsystem-types/Cargo.toml @@ -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" diff --git a/node/subsystem-types/src/lib.rs b/node/subsystem-types/src/lib.rs index f6ff9bea7374..b5a8c67fc581 100644 --- a/node/subsystem-types/src/lib.rs +++ b/node/subsystem-types/src/lib.rs @@ -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; diff --git a/node/subsystem-types/src/runtime_client.rs b/node/subsystem-types/src/runtime_client.rs new file mode 100644 index 000000000000..2aa9e2bffb82 --- /dev/null +++ b/node/subsystem-types/src/runtime_client.rs @@ -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 . + +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, ApiError>; + + // === ParachainHost API === + + /// Get the current validators. + async fn validators(&self, at: Hash) -> Result, 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>, GroupRotationInfo), 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>, 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>, 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, 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; + + /// 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; + + /// 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, 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>, ApiError>; + + /// Get a vector of events concerning candidates that occurred within a block. + async fn candidate_events(&self, at: Hash) -> Result>, 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>, 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>>, ApiError>; + + /// Get the validation code from its hash. + async fn validation_code_by_hash( + &self, + at: Hash, + hash: ValidationCodeHash, + ) -> Result, ApiError>; + + /// Scrape dispute relevant from on-chain, backing votes and resolved disputes. + async fn on_chain_votes(&self, at: Hash) + -> Result>, 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, 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, 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, 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, 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)>, ApiError>; + + // === BABE API === + + /// Returns information regarding the current epoch. + async fn current_epoch(&self, at: Hash) -> Result; + + // === AuthorityDiscovery API === + + /// Retrieve authority identifiers of the current and next authority set. + async fn authorities( + &self, + at: Hash, + ) -> std::result::Result, ApiError>; +} + +#[async_trait] +impl RuntimeApiSubsystemClient for T +where + T: ProvideRuntimeApi + Send + Sync, + T::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, +{ + async fn validators(&self, at: Hash) -> Result, ApiError> { + self.runtime_api().validators(&BlockId::Hash(at)) + } + + async fn validator_groups( + &self, + at: Hash, + ) -> Result<(Vec>, GroupRotationInfo), ApiError> { + self.runtime_api().validator_groups(&BlockId::Hash(at)) + } + + async fn availability_cores( + &self, + at: Hash, + ) -> Result>, ApiError> { + self.runtime_api().availability_cores(&BlockId::Hash(at)) + } + + async fn persisted_validation_data( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result>, 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, 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 { + self.runtime_api() + .check_validation_outputs(&BlockId::Hash(at), para_id, outputs) + } + + async fn session_index_for_child(&self, at: Hash) -> Result { + self.runtime_api().session_index_for_child(&BlockId::Hash(at)) + } + + async fn validation_code( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError> { + self.runtime_api().validation_code(&BlockId::Hash(at), para_id, assumption) + } + + async fn candidate_pending_availability( + &self, + at: Hash, + para_id: Id, + ) -> Result>, ApiError> { + self.runtime_api().candidate_pending_availability(&BlockId::Hash(at), para_id) + } + + async fn candidate_events(&self, at: Hash) -> Result>, ApiError> { + self.runtime_api().candidate_events(&BlockId::Hash(at)) + } + + async fn dmq_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>, ApiError> { + self.runtime_api().dmq_contents(&BlockId::Hash(at), recipient) + } + + async fn inbound_hrmp_channels_contents( + &self, + at: Hash, + recipient: Id, + ) -> Result>>, ApiError> { + self.runtime_api().inbound_hrmp_channels_contents(&BlockId::Hash(at), recipient) + } + + async fn validation_code_by_hash( + &self, + at: Hash, + hash: ValidationCodeHash, + ) -> Result, ApiError> { + self.runtime_api().validation_code_by_hash(&BlockId::Hash(at), hash) + } + + async fn on_chain_votes( + &self, + at: Hash, + ) -> Result>, ApiError> { + self.runtime_api().on_chain_votes(&BlockId::Hash(at)) + } + + async fn session_info( + &self, + at: Hash, + index: SessionIndex, + ) -> Result, 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, ApiError> { + self.runtime_api().pvfs_require_precheck(&BlockId::Hash(at)) + } + + async fn validation_code_hash( + &self, + at: Hash, + para_id: Id, + assumption: OccupiedCoreAssumption, + ) -> Result, ApiError> { + self.runtime_api().validation_code_hash(&BlockId::Hash(at), para_id, assumption) + } + + async fn current_epoch(&self, at: Hash) -> Result { + self.runtime_api().current_epoch(&BlockId::Hash(at)) + } + + async fn authorities( + &self, + at: Hash, + ) -> std::result::Result, ApiError> { + self.runtime_api().authorities(&BlockId::Hash(at)) + } + + async fn api_version_parachain_host(&self, at: Hash) -> Result, ApiError> { + self.runtime_api().api_version::>(&BlockId::Hash(at)) + } + + #[warn(deprecated)] + async fn session_info_before_version_2( + &self, + at: Hash, + index: SessionIndex, + ) -> Result, ApiError> { + #[allow(deprecated)] + self.runtime_api().session_info_before_version_2(&BlockId::Hash(at), index) + } + + async fn staging_get_disputes( + &self, + at: Hash, + ) -> Result)>, ApiError> { + self.runtime_api().staging_get_disputes(&BlockId::Hash(at)) + } +} diff --git a/rustfmt.toml b/rustfmt.toml index 9b872649d842..542c561edd42 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -21,3 +21,4 @@ use_field_init_shorthand = true ignore = [ "bridges", ] +edition = "2021"