feat: initialize Kurdistan SDK - independent fork of Polkadot SDK
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
[package]
|
||||
name = "pezkuwi-node-subsystem-types"
|
||||
description = "Subsystem traits and message definitions"
|
||||
version = "7.0.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
derive_more = { workspace = true, default-features = true }
|
||||
fatality = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
orchestra = { features = ["futures_channel"], workspace = true }
|
||||
pezkuwi-node-network-protocol = { workspace = true, default-features = true }
|
||||
pezkuwi-node-primitives = { workspace = true, default-features = true }
|
||||
pezkuwi-primitives = { workspace = true, default-features = true }
|
||||
pezkuwi-statement-table = { workspace = true, default-features = true }
|
||||
prometheus-endpoint = { workspace = true, default-features = true }
|
||||
sc-client-api = { workspace = true, default-features = true }
|
||||
sc-network = { workspace = true, default-features = true }
|
||||
sc-network-types = { workspace = true, default-features = true }
|
||||
sc-transaction-pool-api = { workspace = true, default-features = true }
|
||||
smallvec = { workspace = true, default-features = true }
|
||||
sp-api = { workspace = true, default-features = true }
|
||||
sp-authority-discovery = { workspace = true, default-features = true }
|
||||
sp-blockchain = { workspace = true, default-features = true }
|
||||
sp-consensus-babe = { workspace = true, default-features = true }
|
||||
sp-runtime = { workspace = true, default-features = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
[features]
|
||||
runtime-benchmarks = [
|
||||
"pezkuwi-node-network-protocol/runtime-benchmarks",
|
||||
"pezkuwi-node-primitives/runtime-benchmarks",
|
||||
"pezkuwi-primitives/runtime-benchmarks",
|
||||
"pezkuwi-statement-table/runtime-benchmarks",
|
||||
"sc-client-api/runtime-benchmarks",
|
||||
"sc-network/runtime-benchmarks",
|
||||
"sc-transaction-pool-api/runtime-benchmarks",
|
||||
"sp-api/runtime-benchmarks",
|
||||
"sp-authority-discovery/runtime-benchmarks",
|
||||
"sp-blockchain/runtime-benchmarks",
|
||||
"sp-consensus-babe/runtime-benchmarks",
|
||||
"sp-runtime/runtime-benchmarks",
|
||||
]
|
||||
@@ -0,0 +1,152 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi 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.
|
||||
|
||||
// Pezkuwi 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 Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Error types for the subsystem requests.
|
||||
|
||||
use ::orchestra::OrchestraError as OverseerError;
|
||||
use fatality::fatality;
|
||||
|
||||
/// A description of an error causing the runtime API request to be unservable.
|
||||
#[derive(thiserror::Error, Debug, Clone)]
|
||||
pub enum RuntimeApiError {
|
||||
/// The runtime API cannot be executed due to a runtime error.
|
||||
#[error("The runtime API '{runtime_api_name}' cannot be executed: {source}")]
|
||||
Execution {
|
||||
/// The runtime API being called
|
||||
runtime_api_name: &'static str,
|
||||
/// The wrapped error. Marked as source for tracking the error chain.
|
||||
#[source]
|
||||
source: std::sync::Arc<dyn 'static + std::error::Error + Send + Sync>,
|
||||
},
|
||||
|
||||
/// The runtime API request in question cannot be executed because the runtime at the requested
|
||||
/// relay-parent is an old version.
|
||||
#[error("The API is not supported by the runtime at the relay-parent")]
|
||||
NotSupported {
|
||||
/// The runtime API being called
|
||||
runtime_api_name: &'static str,
|
||||
},
|
||||
}
|
||||
|
||||
/// A description of an error causing the chain API request to be unservable.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ChainApiError {
|
||||
msg: String,
|
||||
}
|
||||
|
||||
impl From<&str> for ChainApiError {
|
||||
fn from(s: &str) -> Self {
|
||||
s.to_owned().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for ChainApiError {
|
||||
fn from(msg: String) -> Self {
|
||||
Self { msg }
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ChainApiError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
write!(f, "{}", self.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ChainApiError {}
|
||||
|
||||
/// An error that may happen during Availability Recovery process.
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[fatality(splitable)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum RecoveryError {
|
||||
#[error("Invalid data")]
|
||||
Invalid,
|
||||
|
||||
#[error("Data is unavailable")]
|
||||
Unavailable,
|
||||
|
||||
#[fatal]
|
||||
#[error("Erasure task channel closed")]
|
||||
ChannelClosed,
|
||||
}
|
||||
|
||||
/// An error type that describes faults that may happen
|
||||
///
|
||||
/// These are:
|
||||
/// * Channels being closed
|
||||
/// * Subsystems dying when they are not expected to
|
||||
/// * Subsystems not dying when they are told to die
|
||||
/// * etc.
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum SubsystemError {
|
||||
#[error(transparent)]
|
||||
NotifyCancellation(#[from] futures::channel::oneshot::Canceled),
|
||||
|
||||
#[error(transparent)]
|
||||
QueueError(#[from] futures::channel::mpsc::SendError),
|
||||
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Infallible(#[from] std::convert::Infallible),
|
||||
|
||||
#[error(transparent)]
|
||||
Prometheus(#[from] prometheus_endpoint::PrometheusError),
|
||||
|
||||
#[error("Failed to {0}")]
|
||||
Context(String),
|
||||
|
||||
#[error("Subsystem stalled: {0}")]
|
||||
SubsystemStalled(&'static str),
|
||||
|
||||
/// Generated by the `#[overseer(..)]` proc-macro
|
||||
#[error(transparent)]
|
||||
Generated(#[from] OverseerError),
|
||||
|
||||
/// Per origin (or subsystem) annotations to wrap an error.
|
||||
#[error("Error originated in {origin}")]
|
||||
FromOrigin {
|
||||
/// An additional annotation tag for the origin of `source`.
|
||||
origin: &'static str,
|
||||
/// The wrapped error. Marked as source for tracking the error chain.
|
||||
#[source]
|
||||
source: Box<dyn 'static + std::error::Error + Send + Sync>,
|
||||
},
|
||||
}
|
||||
|
||||
// impl AnnotateErrorOrigin for SubsystemError {
|
||||
// fn with_origin(self, origin: &'static str) -> Self {
|
||||
// Self::FromOrigin {
|
||||
// origin,
|
||||
// source: Box::new(self),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl SubsystemError {
|
||||
/// Adds a `str` as `origin` to the given error `err`.
|
||||
pub fn with_origin<E: 'static + Send + Sync + std::error::Error>(
|
||||
origin: &'static str,
|
||||
err: E,
|
||||
) -> Self {
|
||||
Self::FromOrigin { origin, source: Box::new(err) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Ease the use of subsystem errors.
|
||||
pub type SubsystemResult<T> = Result<T, self::SubsystemError>;
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi 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.
|
||||
|
||||
// Pezkuwi 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 Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Subsystem trait definitions and message types.
|
||||
//!
|
||||
//! Node-side logic for Pezkuwi is mostly comprised of Subsystems, which are discrete components
|
||||
//! that communicate via message-passing. They are coordinated by an overseer, provided by a
|
||||
//! separate crate.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
|
||||
pub use pezkuwi_primitives::{Block, BlockNumber, Hash};
|
||||
|
||||
/// Keeps the state of a specific block pinned in memory while the handle is alive.
|
||||
///
|
||||
/// The handle is reference counted and once the last is dropped, the
|
||||
/// block is unpinned.
|
||||
///
|
||||
/// This is useful for runtime API calls to blocks that are
|
||||
/// racing against finality, e.g. for slashing purposes.
|
||||
pub type UnpinHandle = sc_client_api::UnpinHandle<Block>;
|
||||
|
||||
pub mod errors;
|
||||
pub mod messages;
|
||||
|
||||
mod runtime_client;
|
||||
pub use runtime_client::{ChainApiBackend, DefaultSubsystemClient, RuntimeApiSubsystemClient};
|
||||
|
||||
/// How many slots are stack-reserved for active leaves updates
|
||||
///
|
||||
/// If there are fewer than this number of slots, then we've wasted some stack space.
|
||||
/// If there are greater than this number of slots, then we fall back to a heap vector.
|
||||
const ACTIVE_LEAVES_SMALLVEC_CAPACITY: usize = 8;
|
||||
|
||||
/// Activated leaf.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ActivatedLeaf {
|
||||
/// The block hash.
|
||||
pub hash: Hash,
|
||||
/// The block number.
|
||||
pub number: BlockNumber,
|
||||
/// A handle to unpin the block on drop.
|
||||
pub unpin_handle: UnpinHandle,
|
||||
}
|
||||
|
||||
/// Changes in the set of active leaves: the teyrchain heads which we care to work on.
|
||||
///
|
||||
/// Note that the activated and deactivated fields indicate deltas, not complete sets.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ActiveLeavesUpdate {
|
||||
/// New relay chain block of interest.
|
||||
pub activated: Option<ActivatedLeaf>,
|
||||
/// Relay chain block hashes no longer of interest.
|
||||
pub deactivated: SmallVec<[Hash; ACTIVE_LEAVES_SMALLVEC_CAPACITY]>,
|
||||
}
|
||||
|
||||
impl ActiveLeavesUpdate {
|
||||
/// Create a `ActiveLeavesUpdate` with a single activated hash
|
||||
pub fn start_work(activated: ActivatedLeaf) -> Self {
|
||||
Self { activated: Some(activated), ..Default::default() }
|
||||
}
|
||||
|
||||
/// Create a `ActiveLeavesUpdate` with a single deactivated hash
|
||||
pub fn stop_work(hash: Hash) -> Self {
|
||||
Self { deactivated: [hash][..].into(), ..Default::default() }
|
||||
}
|
||||
|
||||
/// Is this update empty and doesn't contain any information?
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.activated.is_none() && self.deactivated.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ActiveLeavesUpdate {
|
||||
/// Equality for `ActiveLeavesUpdate` doesn't imply bitwise equality.
|
||||
///
|
||||
/// Instead, it means equality when `activated` and `deactivated` are considered as sets.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.activated.as_ref().map(|a| a.hash) == other.activated.as_ref().map(|a| a.hash) &&
|
||||
self.deactivated.len() == other.deactivated.len() &&
|
||||
self.deactivated.iter().all(|a| other.deactivated.contains(a))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ActiveLeavesUpdate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ActiveLeavesUpdate")
|
||||
.field("activated", &self.activated)
|
||||
.field("deactivated", &self.deactivated)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Signals sent by an overseer to a subsystem.
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub enum OverseerSignal {
|
||||
/// Subsystems should adjust their jobs to start and stop work on appropriate block hashes.
|
||||
ActiveLeaves(ActiveLeavesUpdate),
|
||||
/// `Subsystem` is informed of a finalized block by its block hash and number.
|
||||
BlockFinalized(Hash, BlockNumber),
|
||||
/// Conclude the work of the `Overseer` and all `Subsystem`s.
|
||||
Conclude,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,112 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi 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.
|
||||
|
||||
// Pezkuwi 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 Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub use sc_network::ReputationChange;
|
||||
pub use sc_network_types::PeerId;
|
||||
|
||||
use pezkuwi_node_network_protocol::{
|
||||
grid_topology::SessionGridTopology, peer_set::ProtocolVersion, ObservedRole, OurView, View,
|
||||
WrongVariant,
|
||||
};
|
||||
use pezkuwi_primitives::{AuthorityDiscoveryId, SessionIndex, ValidatorIndex};
|
||||
|
||||
/// A struct indicating new gossip topology.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct NewGossipTopology {
|
||||
/// The session index this topology corresponds to.
|
||||
pub session: SessionIndex,
|
||||
/// The topology itself.
|
||||
pub topology: SessionGridTopology,
|
||||
/// The local validator index, if any.
|
||||
pub local_index: Option<ValidatorIndex>,
|
||||
}
|
||||
|
||||
/// Events from network.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum NetworkBridgeEvent<M> {
|
||||
/// A peer has connected.
|
||||
PeerConnected(PeerId, ObservedRole, ProtocolVersion, Option<HashSet<AuthorityDiscoveryId>>),
|
||||
|
||||
/// A peer has disconnected.
|
||||
PeerDisconnected(PeerId),
|
||||
|
||||
/// Our neighbors in the new gossip topology for the session.
|
||||
/// We're not necessarily connected to all of them.
|
||||
///
|
||||
/// This message is issued only on the validation peer set.
|
||||
///
|
||||
/// Note, that the distribution subsystems need to handle the last
|
||||
/// view update of the newly added gossip peers manually.
|
||||
NewGossipTopology(NewGossipTopology),
|
||||
|
||||
/// Peer has sent a message.
|
||||
PeerMessage(PeerId, M),
|
||||
|
||||
/// Peer's `View` has changed.
|
||||
PeerViewChange(PeerId, View),
|
||||
|
||||
/// Our view has changed.
|
||||
OurViewChange(OurView),
|
||||
|
||||
/// The authority discovery session key has been rotated.
|
||||
UpdatedAuthorityIds(PeerId, HashSet<AuthorityDiscoveryId>),
|
||||
}
|
||||
|
||||
impl<M> NetworkBridgeEvent<M> {
|
||||
/// Focus an overarching network-bridge event into some more specific variant.
|
||||
///
|
||||
/// This tries to transform M in `PeerMessage` to a message type specific to a subsystem.
|
||||
/// It is used to dispatch events coming from a peer set to the various subsystems that are
|
||||
/// handled within that peer set. More concretely a `ValidationProtocol` will be transformed
|
||||
/// for example into a `BitfieldDistributionMessage` in case of the `BitfieldDistribution`
|
||||
/// constructor.
|
||||
///
|
||||
/// Therefore a `NetworkBridgeEvent<ValidationProtocol>` will become for example a
|
||||
/// `NetworkBridgeEvent<BitfieldDistributionMessage>`, with the more specific message type
|
||||
/// `BitfieldDistributionMessage`.
|
||||
///
|
||||
/// This acts as a call to `clone`, except in the case where the event is a message event,
|
||||
/// in which case the clone can be expensive and it only clones if the message type can
|
||||
/// be focused.
|
||||
pub fn focus<'a, T>(&'a self) -> Result<NetworkBridgeEvent<T>, WrongVariant>
|
||||
where
|
||||
T: 'a + Clone,
|
||||
T: TryFrom<&'a M, Error = WrongVariant>,
|
||||
{
|
||||
Ok(match *self {
|
||||
NetworkBridgeEvent::PeerMessage(ref peer, ref msg) =>
|
||||
NetworkBridgeEvent::PeerMessage(*peer, T::try_from(msg)?),
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
ref peer,
|
||||
ref role,
|
||||
ref version,
|
||||
ref authority_id,
|
||||
) => NetworkBridgeEvent::PeerConnected(*peer, *role, *version, authority_id.clone()),
|
||||
NetworkBridgeEvent::PeerDisconnected(ref peer) =>
|
||||
NetworkBridgeEvent::PeerDisconnected(*peer),
|
||||
NetworkBridgeEvent::NewGossipTopology(ref topology) =>
|
||||
NetworkBridgeEvent::NewGossipTopology(topology.clone()),
|
||||
NetworkBridgeEvent::PeerViewChange(ref peer, ref view) =>
|
||||
NetworkBridgeEvent::PeerViewChange(*peer, view.clone()),
|
||||
NetworkBridgeEvent::OurViewChange(ref view) =>
|
||||
NetworkBridgeEvent::OurViewChange(view.clone()),
|
||||
NetworkBridgeEvent::UpdatedAuthorityIds(ref peer, ref authority_ids) =>
|
||||
NetworkBridgeEvent::UpdatedAuthorityIds(*peer, authority_ids.clone()),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,730 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi 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.
|
||||
|
||||
// Pezkuwi 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 Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use pezkuwi_primitives::{
|
||||
async_backing::{self, Constraints},
|
||||
runtime_api::TeyrchainHost,
|
||||
slashing, ApprovalVotingParams, Block, BlockNumber, CandidateCommitments, CandidateEvent,
|
||||
CandidateHash, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, CoreState,
|
||||
DisputeState, ExecutorParams, GroupRotationInfo, Hash, Header, Id, InboundDownwardMessage,
|
||||
InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, PersistedValidationData,
|
||||
PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode,
|
||||
ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
};
|
||||
use sc_client_api::{AuxStore, HeaderBackend};
|
||||
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
|
||||
use sp_api::{ApiError, ApiExt, ProvideRuntimeApi};
|
||||
use sp_authority_discovery::AuthorityDiscoveryApi;
|
||||
use sp_blockchain::{BlockStatus, Info};
|
||||
use sp_consensus_babe::{BabeApi, Epoch};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||
use std::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
/// Offers header utilities.
|
||||
///
|
||||
/// This is a async wrapper trait for ['HeaderBackend'] to be used with the
|
||||
/// `ChainApiSubsystem`.
|
||||
// This trait was introduced to suit the needs of collators. Depending on their operating mode, they
|
||||
// might not have a client of the relay chain that can supply a synchronous HeaderBackend
|
||||
// implementation.
|
||||
#[async_trait]
|
||||
pub trait ChainApiBackend: Send + Sync {
|
||||
/// Get block header. Returns `None` if block is not found.
|
||||
async fn header(&self, hash: Hash) -> sp_blockchain::Result<Option<Header>>;
|
||||
/// Get blockchain info.
|
||||
async fn info(&self) -> sp_blockchain::Result<Info<Block>>;
|
||||
/// Get block number by hash. Returns `None` if the header is not in the chain.
|
||||
async fn number(
|
||||
&self,
|
||||
hash: Hash,
|
||||
) -> sp_blockchain::Result<Option<<Header as HeaderT>::Number>>;
|
||||
/// Get block hash by number. Returns `None` if the header is not in the chain.
|
||||
async fn hash(&self, number: NumberFor<Block>) -> sp_blockchain::Result<Option<Hash>>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T> ChainApiBackend for T
|
||||
where
|
||||
T: HeaderBackend<Block>,
|
||||
{
|
||||
/// Get block header. Returns `None` if block is not found.
|
||||
async fn header(&self, hash: Hash) -> sp_blockchain::Result<Option<Header>> {
|
||||
HeaderBackend::header(self, hash)
|
||||
}
|
||||
|
||||
/// Get blockchain info.
|
||||
async fn info(&self) -> sp_blockchain::Result<Info<Block>> {
|
||||
Ok(HeaderBackend::info(self))
|
||||
}
|
||||
|
||||
/// Get block number by hash. Returns `None` if the header is not in the chain.
|
||||
async fn number(
|
||||
&self,
|
||||
hash: Hash,
|
||||
) -> sp_blockchain::Result<Option<<Header as HeaderT>::Number>> {
|
||||
HeaderBackend::number(self, hash)
|
||||
}
|
||||
|
||||
/// Get block hash by number. Returns `None` if the header is not in the chain.
|
||||
async fn hash(&self, number: NumberFor<Block>) -> sp_blockchain::Result<Option<Hash>> {
|
||||
HeaderBackend::hash(self, number)
|
||||
}
|
||||
}
|
||||
|
||||
/// Exposes all runtime calls that are used by the runtime API subsystem.
|
||||
#[async_trait]
|
||||
pub trait RuntimeApiSubsystemClient {
|
||||
/// Teyrchain host API version
|
||||
async fn api_version_teyrchain_host(&self, at: Hash) -> Result<Option<u32>, ApiError>;
|
||||
|
||||
// === TeyrchainHost 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 teyrchain host version 2.
|
||||
async fn session_info(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<SessionInfo>, ApiError>;
|
||||
|
||||
/// Submits a PVF pre-checking statement into the transaction pool.
|
||||
///
|
||||
/// NOTE: This function is only available since teyrchain 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 teyrchain 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 teyrchain host version 2.
|
||||
async fn validation_code_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCodeHash>, ApiError>;
|
||||
|
||||
/***** Added in v3 **** */
|
||||
|
||||
/// Returns all onchain disputes.
|
||||
async fn disputes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError>;
|
||||
|
||||
/// Returns a list of validators that lost a past session dispute and need to be slashed.
|
||||
async fn unapplied_slashes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)>, ApiError>;
|
||||
|
||||
/// Returns a merkle proof of a validator session key in a past session.
|
||||
async fn key_ownership_proof(
|
||||
&self,
|
||||
at: Hash,
|
||||
validator_id: ValidatorId,
|
||||
) -> Result<Option<slashing::OpaqueKeyOwnershipProof>, ApiError>;
|
||||
|
||||
/// Submits an unsigned extrinsic to slash validators who lost a dispute about
|
||||
/// a candidate of a past session.
|
||||
async fn submit_report_dispute_lost(
|
||||
&self,
|
||||
at: Hash,
|
||||
dispute_proof: slashing::DisputeProof,
|
||||
key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
|
||||
) -> Result<Option<()>, 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>;
|
||||
|
||||
/// Get the execution environment parameter set by parent hash, if stored
|
||||
async fn session_executor_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
session_index: SessionIndex,
|
||||
) -> Result<Option<ExecutorParams>, ApiError>;
|
||||
|
||||
// === v6 ===
|
||||
/// Get the minimum number of backing votes.
|
||||
async fn minimum_backing_votes(
|
||||
&self,
|
||||
at: Hash,
|
||||
session_index: SessionIndex,
|
||||
) -> Result<u32, ApiError>;
|
||||
|
||||
// === v7: Asynchronous backing API ===
|
||||
|
||||
/// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
|
||||
async fn async_backing_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<pezkuwi_primitives::AsyncBackingParams, ApiError>;
|
||||
|
||||
/// Returns the state of teyrchain backing for a given para.
|
||||
/// This is a staging method! Do not use on production runtimes!
|
||||
async fn para_backing_state(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<async_backing::BackingState>, ApiError>;
|
||||
|
||||
// === v8 ===
|
||||
|
||||
/// Gets the disabled validators at a specific block height
|
||||
async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError>;
|
||||
|
||||
// === v9 ===
|
||||
/// Get the node features.
|
||||
async fn node_features(&self, at: Hash) -> Result<NodeFeatures, ApiError>;
|
||||
|
||||
// == v10: Approval voting params ==
|
||||
/// Approval voting configuration parameters
|
||||
async fn approval_voting_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
session_index: SessionIndex,
|
||||
) -> Result<ApprovalVotingParams, ApiError>;
|
||||
|
||||
// == v11: Claim queue ==
|
||||
/// Fetch the `ClaimQueue` from scheduler pallet
|
||||
async fn claim_queue(&self, at: Hash) -> Result<BTreeMap<CoreIndex, VecDeque<Id>>, ApiError>;
|
||||
|
||||
// == v11: Elastic scaling support ==
|
||||
/// Get the receipts of all candidates pending availability for a `ParaId`.
|
||||
async fn candidates_pending_availability(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Vec<CommittedCandidateReceipt<Hash>>, ApiError>;
|
||||
|
||||
// == v12 ==
|
||||
/// Get the constraints on the actions that can be taken by a new teyrchain
|
||||
/// block.
|
||||
async fn backing_constraints(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<Constraints>, ApiError>;
|
||||
|
||||
// === v12 ===
|
||||
/// Fetch the scheduling lookahead value
|
||||
async fn scheduling_lookahead(&self, at: Hash) -> Result<u32, ApiError>;
|
||||
|
||||
// === v12 ===
|
||||
/// Fetch the maximum uncompressed code size.
|
||||
async fn validation_code_bomb_limit(&self, at: Hash) -> Result<u32, ApiError>;
|
||||
|
||||
// == v14 ==
|
||||
/// Fetch the list of all teyrchain IDs registered in the relay chain.
|
||||
async fn para_ids(&self, at: Hash) -> Result<Vec<Id>, ApiError>;
|
||||
|
||||
// == v15 ==
|
||||
/// Returns a list of validators that lost a past session dispute and need to be slashed (v2).
|
||||
async fn unapplied_slashes_v2(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>, ApiError>;
|
||||
}
|
||||
|
||||
/// Default implementation of [`RuntimeApiSubsystemClient`] using the client.
|
||||
pub struct DefaultSubsystemClient<Client> {
|
||||
client: Arc<Client>,
|
||||
offchain_transaction_pool_factory: OffchainTransactionPoolFactory<Block>,
|
||||
}
|
||||
|
||||
impl<Client> DefaultSubsystemClient<Client> {
|
||||
/// Create new instance.
|
||||
pub fn new(
|
||||
client: Arc<Client>,
|
||||
offchain_transaction_pool_factory: OffchainTransactionPoolFactory<Block>,
|
||||
) -> Self {
|
||||
Self { client, offchain_transaction_pool_factory }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<Client> RuntimeApiSubsystemClient for DefaultSubsystemClient<Client>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block> + Send + Sync,
|
||||
Client::Api: TeyrchainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
|
||||
{
|
||||
async fn validators(&self, at: Hash) -> Result<Vec<ValidatorId>, ApiError> {
|
||||
self.client.runtime_api().validators(at)
|
||||
}
|
||||
|
||||
async fn validator_groups(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>), ApiError> {
|
||||
self.client.runtime_api().validator_groups(at)
|
||||
}
|
||||
|
||||
async fn availability_cores(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<CoreState<Hash, BlockNumber>>, ApiError> {
|
||||
self.client.runtime_api().availability_cores(at)
|
||||
}
|
||||
|
||||
async fn persisted_validation_data(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<PersistedValidationData<Hash, BlockNumber>>, ApiError> {
|
||||
self.client.runtime_api().persisted_validation_data(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.client.runtime_api().assumed_validation_data(
|
||||
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.client.runtime_api().check_validation_outputs(at, para_id, outputs)
|
||||
}
|
||||
|
||||
async fn session_index_for_child(&self, at: Hash) -> Result<SessionIndex, ApiError> {
|
||||
self.client.runtime_api().session_index_for_child(at)
|
||||
}
|
||||
|
||||
async fn validation_code(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCode>, ApiError> {
|
||||
self.client.runtime_api().validation_code(at, para_id, assumption)
|
||||
}
|
||||
|
||||
async fn candidate_pending_availability(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<CommittedCandidateReceipt<Hash>>, ApiError> {
|
||||
self.client.runtime_api().candidate_pending_availability(at, para_id)
|
||||
}
|
||||
|
||||
async fn candidates_pending_availability(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Vec<CommittedCandidateReceipt<Hash>>, ApiError> {
|
||||
self.client.runtime_api().candidates_pending_availability(at, para_id)
|
||||
}
|
||||
|
||||
async fn candidate_events(&self, at: Hash) -> Result<Vec<CandidateEvent<Hash>>, ApiError> {
|
||||
self.client.runtime_api().candidate_events(at)
|
||||
}
|
||||
|
||||
async fn dmq_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<Vec<InboundDownwardMessage<BlockNumber>>, ApiError> {
|
||||
self.client.runtime_api().dmq_contents(at, recipient)
|
||||
}
|
||||
|
||||
async fn inbound_hrmp_channels_contents(
|
||||
&self,
|
||||
at: Hash,
|
||||
recipient: Id,
|
||||
) -> Result<BTreeMap<Id, Vec<InboundHrmpMessage<BlockNumber>>>, ApiError> {
|
||||
self.client.runtime_api().inbound_hrmp_channels_contents(at, recipient)
|
||||
}
|
||||
|
||||
async fn validation_code_by_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
hash: ValidationCodeHash,
|
||||
) -> Result<Option<ValidationCode>, ApiError> {
|
||||
self.client.runtime_api().validation_code_by_hash(at, hash)
|
||||
}
|
||||
|
||||
async fn on_chain_votes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Option<ScrapedOnChainVotes<Hash>>, ApiError> {
|
||||
self.client.runtime_api().on_chain_votes(at)
|
||||
}
|
||||
|
||||
async fn session_executor_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
session_index: SessionIndex,
|
||||
) -> Result<Option<ExecutorParams>, ApiError> {
|
||||
self.client.runtime_api().session_executor_params(at, session_index)
|
||||
}
|
||||
|
||||
async fn session_info(
|
||||
&self,
|
||||
at: Hash,
|
||||
index: SessionIndex,
|
||||
) -> Result<Option<SessionInfo>, ApiError> {
|
||||
self.client.runtime_api().session_info(at, index)
|
||||
}
|
||||
|
||||
async fn submit_pvf_check_statement(
|
||||
&self,
|
||||
at: Hash,
|
||||
stmt: PvfCheckStatement,
|
||||
signature: ValidatorSignature,
|
||||
) -> Result<(), ApiError> {
|
||||
let mut runtime_api = self.client.runtime_api();
|
||||
|
||||
runtime_api.register_extension(
|
||||
self.offchain_transaction_pool_factory.offchain_transaction_pool(at),
|
||||
);
|
||||
|
||||
runtime_api.submit_pvf_check_statement(at, stmt, signature)
|
||||
}
|
||||
|
||||
async fn pvfs_require_precheck(&self, at: Hash) -> Result<Vec<ValidationCodeHash>, ApiError> {
|
||||
self.client.runtime_api().pvfs_require_precheck(at)
|
||||
}
|
||||
|
||||
async fn validation_code_hash(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
assumption: OccupiedCoreAssumption,
|
||||
) -> Result<Option<ValidationCodeHash>, ApiError> {
|
||||
self.client.runtime_api().validation_code_hash(at, para_id, assumption)
|
||||
}
|
||||
|
||||
async fn current_epoch(&self, at: Hash) -> Result<Epoch, ApiError> {
|
||||
self.client.runtime_api().current_epoch(at)
|
||||
}
|
||||
|
||||
async fn authorities(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> std::result::Result<Vec<sp_authority_discovery::AuthorityId>, ApiError> {
|
||||
self.client.runtime_api().authorities(at)
|
||||
}
|
||||
|
||||
async fn api_version_teyrchain_host(&self, at: Hash) -> Result<Option<u32>, ApiError> {
|
||||
self.client.runtime_api().api_version::<dyn TeyrchainHost<Block>>(at)
|
||||
}
|
||||
|
||||
async fn disputes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
|
||||
self.client.runtime_api().disputes(at)
|
||||
}
|
||||
|
||||
async fn unapplied_slashes(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)>, ApiError> {
|
||||
self.client.runtime_api().unapplied_slashes(at)
|
||||
}
|
||||
|
||||
async fn unapplied_slashes_v2(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>, ApiError> {
|
||||
self.client.runtime_api().unapplied_slashes_v2(at)
|
||||
}
|
||||
|
||||
async fn key_ownership_proof(
|
||||
&self,
|
||||
at: Hash,
|
||||
validator_id: ValidatorId,
|
||||
) -> Result<Option<slashing::OpaqueKeyOwnershipProof>, ApiError> {
|
||||
self.client.runtime_api().key_ownership_proof(at, validator_id)
|
||||
}
|
||||
|
||||
async fn submit_report_dispute_lost(
|
||||
&self,
|
||||
at: Hash,
|
||||
dispute_proof: slashing::DisputeProof,
|
||||
key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
|
||||
) -> Result<Option<()>, ApiError> {
|
||||
let mut runtime_api = self.client.runtime_api();
|
||||
|
||||
runtime_api.register_extension(
|
||||
self.offchain_transaction_pool_factory.offchain_transaction_pool(at),
|
||||
);
|
||||
|
||||
runtime_api.submit_report_dispute_lost(at, dispute_proof, key_ownership_proof)
|
||||
}
|
||||
|
||||
async fn minimum_backing_votes(
|
||||
&self,
|
||||
at: Hash,
|
||||
_session_index: SessionIndex,
|
||||
) -> Result<u32, ApiError> {
|
||||
self.client.runtime_api().minimum_backing_votes(at)
|
||||
}
|
||||
|
||||
async fn para_backing_state(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<async_backing::BackingState>, ApiError> {
|
||||
self.client.runtime_api().para_backing_state(at, para_id)
|
||||
}
|
||||
|
||||
async fn async_backing_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
) -> Result<async_backing::AsyncBackingParams, ApiError> {
|
||||
self.client.runtime_api().async_backing_params(at)
|
||||
}
|
||||
|
||||
async fn node_features(&self, at: Hash) -> Result<NodeFeatures, ApiError> {
|
||||
self.client.runtime_api().node_features(at)
|
||||
}
|
||||
|
||||
async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
|
||||
self.client.runtime_api().disabled_validators(at)
|
||||
}
|
||||
|
||||
/// Approval voting configuration parameters
|
||||
async fn approval_voting_params(
|
||||
&self,
|
||||
at: Hash,
|
||||
_session_index: SessionIndex,
|
||||
) -> Result<ApprovalVotingParams, ApiError> {
|
||||
self.client.runtime_api().approval_voting_params(at)
|
||||
}
|
||||
|
||||
async fn claim_queue(&self, at: Hash) -> Result<BTreeMap<CoreIndex, VecDeque<Id>>, ApiError> {
|
||||
self.client.runtime_api().claim_queue(at)
|
||||
}
|
||||
|
||||
async fn backing_constraints(
|
||||
&self,
|
||||
at: Hash,
|
||||
para_id: Id,
|
||||
) -> Result<Option<Constraints>, ApiError> {
|
||||
self.client.runtime_api().backing_constraints(at, para_id)
|
||||
}
|
||||
|
||||
async fn scheduling_lookahead(&self, at: Hash) -> Result<u32, ApiError> {
|
||||
self.client.runtime_api().scheduling_lookahead(at)
|
||||
}
|
||||
|
||||
async fn validation_code_bomb_limit(&self, at: Hash) -> Result<u32, ApiError> {
|
||||
self.client.runtime_api().validation_code_bomb_limit(at)
|
||||
}
|
||||
|
||||
async fn para_ids(&self, at: Hash) -> Result<Vec<Id>, ApiError> {
|
||||
self.client.runtime_api().para_ids(at)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Client, Block> HeaderBackend<Block> for DefaultSubsystemClient<Client>
|
||||
where
|
||||
Client: HeaderBackend<Block>,
|
||||
Block: sp_runtime::traits::Block,
|
||||
{
|
||||
fn header(
|
||||
&self,
|
||||
hash: Block::Hash,
|
||||
) -> sc_client_api::blockchain::Result<Option<Block::Header>> {
|
||||
self.client.header(hash)
|
||||
}
|
||||
|
||||
fn info(&self) -> Info<Block> {
|
||||
self.client.info()
|
||||
}
|
||||
|
||||
fn status(&self, hash: Block::Hash) -> sc_client_api::blockchain::Result<BlockStatus> {
|
||||
self.client.status(hash)
|
||||
}
|
||||
|
||||
fn number(
|
||||
&self,
|
||||
hash: Block::Hash,
|
||||
) -> sc_client_api::blockchain::Result<Option<<<Block as BlockT>::Header as HeaderT>::Number>>
|
||||
{
|
||||
self.client.number(hash)
|
||||
}
|
||||
|
||||
fn hash(
|
||||
&self,
|
||||
number: NumberFor<Block>,
|
||||
) -> sc_client_api::blockchain::Result<Option<Block::Hash>> {
|
||||
self.client.hash(number)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Client> AuxStore for DefaultSubsystemClient<Client>
|
||||
where
|
||||
Client: AuxStore,
|
||||
{
|
||||
fn insert_aux<
|
||||
'a,
|
||||
'b: 'a,
|
||||
'c: 'a,
|
||||
I: IntoIterator<Item = &'a (&'c [u8], &'c [u8])>,
|
||||
D: IntoIterator<Item = &'a &'b [u8]>,
|
||||
>(
|
||||
&self,
|
||||
insert: I,
|
||||
delete: D,
|
||||
) -> sp_blockchain::Result<()> {
|
||||
self.client.insert_aux(insert, delete)
|
||||
}
|
||||
|
||||
fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result<Option<Vec<u8>>> {
|
||||
self.client.get_aux(key)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user