Do not depend on native runtimes for RuntimeApi (#7451)

* Implement runtime apis for fake runtime

These runtime api implementations are only used to make the compiler
think that we have implemented all required runtime apis. They will not
be called as we switch the executor to `WasmExecutor`. In the near
future we will not require these fake implementations anymore after
Substrate has shifted away from this compile time requirement.

This brings us the advantage that the `polkadot-service` doesn't need to
depend on the runtimes for getting the `RuntimeApi` type.

It also removes around 1min of build time on my machine ;)

* Fix warning

* FMT

* ".git/.scripts/commands/fmt/fmt.sh"

* Use more descriptive id

* Fix warnings

* Adapt path

* Fix 🙈

---------

Co-authored-by: command-bot <>
This commit is contained in:
Bastian Köcher
2023-07-04 10:09:14 +02:00
committed by GitHub
parent 77ef85b04d
commit e53d15aa20
19 changed files with 1155 additions and 1507 deletions
+430
View File
@@ -0,0 +1,430 @@
// Copyright (C) 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/>.
//! Code related to benchmarking a [`crate::Client`].
use codec::Encode;
use polkadot_primitives::AccountId;
use sc_client_api::UsageProvider;
use sp_core::{Pair, H256};
use sp_keyring::Sr25519Keyring;
use sp_runtime::OpaqueExtrinsic;
use crate::*;
macro_rules! identify_chain {
(
$chain:expr,
$nonce:ident,
$current_block:ident,
$period:ident,
$genesis:ident,
$signer:ident,
$generic_code:expr $(,)*
) => {
match $chain {
Chain::Polkadot => {
#[cfg(feature = "polkadot-native")]
{
use polkadot_runtime as runtime;
let call = $generic_code;
Ok(polkadot_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
}
#[cfg(not(feature = "polkadot-native"))]
{
Err("`polkadot-native` feature not enabled")
}
},
Chain::Kusama => {
#[cfg(feature = "kusama-native")]
{
use kusama_runtime as runtime;
let call = $generic_code;
Ok(kusama_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
}
#[cfg(not(feature = "kusama-native"))]
{
Err("`kusama-native` feature not enabled")
}
},
Chain::Rococo => {
#[cfg(feature = "rococo-native")]
{
use rococo_runtime as runtime;
let call = $generic_code;
Ok(rococo_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
}
#[cfg(not(feature = "rococo-native"))]
{
Err("`rococo-native` feature not enabled")
}
},
Chain::Westend => {
#[cfg(feature = "westend-native")]
{
use westend_runtime as runtime;
let call = $generic_code;
Ok(westend_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
}
#[cfg(not(feature = "westend-native"))]
{
Err("`westend-native` feature not enabled")
}
},
Chain::Unknown => Err("Unknown chain"),
}
};
}
/// Generates `System::Remark` extrinsics for the benchmarks.
///
/// Note: Should only be used for benchmarking.
pub struct RemarkBuilder {
client: Arc<FullClient>,
chain: Chain,
}
impl RemarkBuilder {
/// Creates a new [`Self`] from the given client.
pub fn new(client: Arc<FullClient>, chain: Chain) -> Self {
Self { client, chain }
}
}
impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder {
fn pallet(&self) -> &str {
"system"
}
fn extrinsic(&self) -> &str {
"remark"
}
fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
let period = polkadot_runtime_common::BlockHashCount::get()
.checked_next_power_of_two()
.map(|c| c / 2)
.unwrap_or(2) as u64;
let genesis = self.client.usage_info().chain.best_hash;
let signer = Sr25519Keyring::Bob.pair();
let current_block = 0;
identify_chain! {
self.chain,
nonce,
current_block,
period,
genesis,
signer,
{
runtime::RuntimeCall::System(
runtime::SystemCall::remark { remark: vec![] }
)
},
}
}
}
/// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks.
///
/// Note: Should only be used for benchmarking.
pub struct TransferKeepAliveBuilder {
client: Arc<FullClient>,
dest: AccountId,
chain: Chain,
}
impl TransferKeepAliveBuilder {
/// Creates a new [`Self`] from the given client and the arguments for the extrinsics.
pub fn new(client: Arc<FullClient>, dest: AccountId, chain: Chain) -> Self {
Self { client, dest, chain }
}
}
impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder {
fn pallet(&self) -> &str {
"balances"
}
fn extrinsic(&self) -> &str {
"transfer_keep_alive"
}
fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
let signer = Sr25519Keyring::Bob.pair();
let period = polkadot_runtime_common::BlockHashCount::get()
.checked_next_power_of_two()
.map(|c| c / 2)
.unwrap_or(2) as u64;
let genesis = self.client.usage_info().chain.best_hash;
let current_block = 0;
identify_chain! {
self.chain,
nonce,
current_block,
period,
genesis,
signer,
{
runtime::RuntimeCall::Balances(runtime::BalancesCall::transfer_keep_alive {
dest: self.dest.clone().into(),
value: runtime::ExistentialDeposit::get(),
})
},
}
}
}
#[cfg(feature = "polkadot-native")]
fn polkadot_sign_call(
call: polkadot_runtime::RuntimeCall,
nonce: u32,
current_block: u64,
period: u64,
genesis: H256,
acc: sp_core::sr25519::Pair,
) -> OpaqueExtrinsic {
use polkadot_runtime as runtime;
let extra: runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
frame_system::CheckGenesis::<runtime::Runtime>::new(),
frame_system::CheckMortality::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
period,
current_block,
)),
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
polkadot_runtime_common::claims::PrevalidateAttests::<runtime::Runtime>::new(),
);
let payload = runtime::SignedPayload::from_raw(
call.clone(),
extra.clone(),
(
(),
runtime::VERSION.spec_version,
runtime::VERSION.transaction_version,
genesis,
genesis,
(),
(),
(),
(),
),
);
let signature = payload.using_encoded(|p| acc.sign(p));
runtime::UncheckedExtrinsic::new_signed(
call,
sp_runtime::AccountId32::from(acc.public()).into(),
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
extra,
)
.into()
}
#[cfg(feature = "westend-native")]
fn westend_sign_call(
call: westend_runtime::RuntimeCall,
nonce: u32,
current_block: u64,
period: u64,
genesis: H256,
acc: sp_core::sr25519::Pair,
) -> OpaqueExtrinsic {
use westend_runtime as runtime;
let extra: runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
frame_system::CheckGenesis::<runtime::Runtime>::new(),
frame_system::CheckMortality::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
period,
current_block,
)),
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
);
let payload = runtime::SignedPayload::from_raw(
call.clone(),
extra.clone(),
(
(),
runtime::VERSION.spec_version,
runtime::VERSION.transaction_version,
genesis,
genesis,
(),
(),
(),
),
);
let signature = payload.using_encoded(|p| acc.sign(p));
runtime::UncheckedExtrinsic::new_signed(
call,
sp_runtime::AccountId32::from(acc.public()).into(),
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
extra,
)
.into()
}
#[cfg(feature = "kusama-native")]
fn kusama_sign_call(
call: kusama_runtime::RuntimeCall,
nonce: u32,
current_block: u64,
period: u64,
genesis: H256,
acc: sp_core::sr25519::Pair,
) -> OpaqueExtrinsic {
use kusama_runtime as runtime;
let extra: runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
frame_system::CheckGenesis::<runtime::Runtime>::new(),
frame_system::CheckMortality::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
period,
current_block,
)),
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
);
let payload = runtime::SignedPayload::from_raw(
call.clone(),
extra.clone(),
(
(),
runtime::VERSION.spec_version,
runtime::VERSION.transaction_version,
genesis,
genesis,
(),
(),
(),
),
);
let signature = payload.using_encoded(|p| acc.sign(p));
runtime::UncheckedExtrinsic::new_signed(
call,
sp_runtime::AccountId32::from(acc.public()).into(),
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
extra,
)
.into()
}
#[cfg(feature = "rococo-native")]
fn rococo_sign_call(
call: rococo_runtime::RuntimeCall,
nonce: u32,
current_block: u64,
period: u64,
genesis: H256,
acc: sp_core::sr25519::Pair,
) -> OpaqueExtrinsic {
use rococo_runtime as runtime;
let extra: runtime::SignedExtra = (
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
frame_system::CheckGenesis::<runtime::Runtime>::new(),
frame_system::CheckMortality::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
period,
current_block,
)),
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
);
let payload = runtime::SignedPayload::from_raw(
call.clone(),
extra.clone(),
(
(),
runtime::VERSION.spec_version,
runtime::VERSION.transaction_version,
genesis,
genesis,
(),
(),
(),
),
);
let signature = payload.using_encoded(|p| acc.sign(p));
runtime::UncheckedExtrinsic::new_signed(
call,
sp_runtime::AccountId32::from(acc.public()).into(),
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
extra,
)
.into()
}
/// Generates inherent data for benchmarking Polkadot, Kusama, Westend and Rococo.
///
/// Not to be used outside of benchmarking since it returns mocked values.
pub fn benchmark_inherent_data(
header: polkadot_core_primitives::Header,
) -> std::result::Result<sp_inherents::InherentData, sp_inherents::Error> {
use sp_inherents::InherentDataProvider;
let mut inherent_data = sp_inherents::InherentData::new();
// Assume that all runtimes have the `timestamp` pallet.
let d = std::time::Duration::from_millis(0);
let timestamp = sp_timestamp::InherentDataProvider::new(d.into());
futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))?;
let para_data = polkadot_primitives::InherentData {
bitfields: Vec::new(),
backed_candidates: Vec::new(),
disputes: Vec::new(),
parent_header: header,
};
inherent_data.put_data(polkadot_primitives::PARACHAINS_INHERENT_IDENTIFIER, &para_data)?;
Ok(inherent_data)
}
+41 -3
View File
@@ -23,6 +23,12 @@ use kusama_runtime as kusama;
#[cfg(feature = "kusama-native")]
use kusama_runtime_constants::currency::UNITS as KSM;
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
use pallet_staking::Forcing;
use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, ValidatorId};
#[cfg(feature = "polkadot-native")]
@@ -36,10 +42,30 @@ use sp_consensus_babe::AuthorityId as BabeId;
use rococo_runtime as rococo;
#[cfg(feature = "rococo-native")]
use rococo_runtime_constants::currency::UNITS as ROC;
use sc_chain_spec::{ChainSpecExtension, ChainType};
use sc_chain_spec::ChainSpecExtension;
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
use sc_chain_spec::ChainType;
use serde::{Deserialize, Serialize};
use sp_core::{sr25519, Pair, Public};
use sp_runtime::{traits::IdentifyAccount, Perbill};
use sp_runtime::traits::IdentifyAccount;
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
use sp_runtime::Perbill;
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
use telemetry::TelemetryEndpoints;
#[cfg(feature = "westend-native")]
use westend_runtime as westend;
@@ -56,6 +82,12 @@ const WESTEND_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/
const ROCOCO_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
#[cfg(feature = "rococo-native")]
const VERSI_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
const DEFAULT_PROTOCOL_ID: &str = "dot";
/// Node `ChainSpec` extensions.
@@ -1271,6 +1303,12 @@ pub fn get_authority_keys_from_seed_no_beefy(
)
}
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
fn testnet_accounts() -> Vec<AccountId> {
vec![
get_account_id_from_seed::<sr25519::Public>("Alice"),
@@ -1667,7 +1705,7 @@ pub fn polkadot_development_config() -> Result<PolkadotChainSpec, String> {
Ok(PolkadotChainSpec::from_genesis(
"Development",
"dev",
"polkadot_dev",
ChainType::Development,
move || polkadot_development_config_genesis(wasm_binary),
vec![],
@@ -0,0 +1,398 @@
// Copyright (C) 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/>.
//! Provides "fake" runtime api implementations
//!
//! These are used to provide a type that implements these runtime apis without requiring to import the native runtimes.
use beefy_primitives::crypto::{AuthorityId as BeefyId, Signature as BeefySignature};
use grandpa_primitives::AuthorityId as GrandpaId;
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
use polkadot_primitives::{
runtime_api, slashing, AccountId, AuthorityDiscoveryId, Balance, Block, BlockNumber,
CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState,
DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
InboundHrmpMessage, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash,
ValidatorId, ValidatorIndex, ValidatorSignature,
};
use sp_core::OpaqueMetadata;
use sp_runtime::{
traits::Block as BlockT,
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
use sp_version::RuntimeVersion;
use sp_weights::Weight;
use std::collections::BTreeMap;
sp_api::decl_runtime_apis! {
/// This runtime api is only implemented for the test runtime!
pub trait GetLastTimestamp {
/// Returns the last timestamp of a runtime.
fn get_last_timestamp() -> u64;
}
}
struct Runtime;
sp_api::impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
unimplemented!()
}
fn execute_block(_: Block) {
unimplemented!()
}
fn initialize_block(_: &<Block as BlockT>::Header) {
unimplemented!()
}
}
impl sp_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
unimplemented!()
}
fn metadata_at_version(_: u32) -> Option<OpaqueMetadata> {
unimplemented!()
}
fn metadata_versions() -> Vec<u32> {
unimplemented!()
}
}
impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(_: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
unimplemented!()
}
fn finalize_block() -> <Block as BlockT>::Header {
unimplemented!()
}
fn inherent_extrinsics(_: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
unimplemented!()
}
fn check_inherents(
_: Block,
_: sp_inherents::InherentData,
) -> sp_inherents::CheckInherentsResult {
unimplemented!()
}
}
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
_: TransactionSource,
_: <Block as BlockT>::Extrinsic,
_: <Block as BlockT>::Hash,
) -> TransactionValidity {
unimplemented!()
}
}
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(_: &<Block as BlockT>::Header) {
unimplemented!()
}
}
impl runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
fn validators() -> Vec<ValidatorId> {
unimplemented!()
}
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
unimplemented!()
}
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
unimplemented!()
}
fn persisted_validation_data(_: ParaId, _: OccupiedCoreAssumption)
-> Option<PersistedValidationData<Hash, BlockNumber>> {
unimplemented!()
}
fn assumed_validation_data(
_: ParaId,
_: Hash,
) -> Option<(PersistedValidationData<Hash, BlockNumber>, ValidationCodeHash)> {
unimplemented!()
}
fn check_validation_outputs(
_: ParaId,
_: CandidateCommitments,
) -> bool {
unimplemented!()
}
fn session_index_for_child() -> SessionIndex {
unimplemented!()
}
fn validation_code(_: ParaId, _: OccupiedCoreAssumption)
-> Option<ValidationCode> {
unimplemented!()
}
fn candidate_pending_availability(_: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
unimplemented!()
}
fn candidate_events() -> Vec<CandidateEvent<Hash>> {
unimplemented!()
}
fn session_info(_: SessionIndex) -> Option<SessionInfo> {
unimplemented!()
}
fn session_executor_params(_: SessionIndex) -> Option<ExecutorParams> {
unimplemented!()
}
fn dmq_contents(_: ParaId) -> Vec<InboundDownwardMessage<BlockNumber>> {
unimplemented!()
}
fn inbound_hrmp_channels_contents(
_: ParaId
) -> BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>> {
unimplemented!()
}
fn validation_code_by_hash(_: ValidationCodeHash) -> Option<ValidationCode> {
unimplemented!()
}
fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>> {
unimplemented!()
}
fn submit_pvf_check_statement(
_: PvfCheckStatement,
_: ValidatorSignature,
) {
unimplemented!()
}
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
unimplemented!()
}
fn validation_code_hash(_: ParaId, _: OccupiedCoreAssumption)
-> Option<ValidationCodeHash>
{
unimplemented!()
}
fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
unimplemented!()
}
fn unapplied_slashes(
) -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)> {
unimplemented!()
}
fn key_ownership_proof(
_: ValidatorId,
) -> Option<slashing::OpaqueKeyOwnershipProof> {
unimplemented!()
}
fn submit_report_dispute_lost(
_: slashing::DisputeProof,
_: slashing::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!()
}
}
impl beefy_primitives::BeefyApi<Block> for Runtime {
fn beefy_genesis() -> Option<BlockNumber> {
unimplemented!()
}
fn validator_set() -> Option<beefy_primitives::ValidatorSet<BeefyId>> {
unimplemented!()
}
fn submit_report_equivocation_unsigned_extrinsic(
_: beefy_primitives::EquivocationProof<
BlockNumber,
BeefyId,
BeefySignature,
>,
_: beefy_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!()
}
fn generate_key_ownership_proof(
_: beefy_primitives::ValidatorSetId,
_: BeefyId,
) -> Option<beefy_primitives::OpaqueKeyOwnershipProof> {
unimplemented!()
}
}
impl sp_mmr_primitives::MmrApi<Block, Hash, BlockNumber> for Runtime {
fn mmr_root() -> Result<Hash, sp_mmr_primitives::Error> {
unimplemented!()
}
fn mmr_leaf_count() -> Result<sp_mmr_primitives::LeafIndex, sp_mmr_primitives::Error> {
unimplemented!()
}
fn generate_proof(
_: Vec<BlockNumber>,
_: Option<BlockNumber>,
) -> Result<(Vec<sp_mmr_primitives::EncodableOpaqueLeaf>, sp_mmr_primitives::Proof<Hash>), sp_mmr_primitives::Error> {
unimplemented!()
}
fn verify_proof(_: Vec<sp_mmr_primitives::EncodableOpaqueLeaf>, _: sp_mmr_primitives::Proof<Hash>)
-> Result<(), sp_mmr_primitives::Error>
{
unimplemented!()
}
fn verify_proof_stateless(
_: Hash,
_: Vec<sp_mmr_primitives::EncodableOpaqueLeaf>,
_: sp_mmr_primitives::Proof<Hash>
) -> Result<(), sp_mmr_primitives::Error> {
unimplemented!()
}
}
impl grandpa_primitives::GrandpaApi<Block> for Runtime {
fn grandpa_authorities() -> Vec<(GrandpaId, u64)> {
unimplemented!()
}
fn current_set_id() -> grandpa_primitives::SetId {
unimplemented!()
}
fn submit_report_equivocation_unsigned_extrinsic(
_: grandpa_primitives::EquivocationProof<
<Block as BlockT>::Hash,
sp_runtime::traits::NumberFor<Block>,
>,
_: grandpa_primitives::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!()
}
fn generate_key_ownership_proof(
_: grandpa_primitives::SetId,
_: grandpa_primitives::AuthorityId,
) -> Option<grandpa_primitives::OpaqueKeyOwnershipProof> {
unimplemented!()
}
}
impl sp_consensus_babe::BabeApi<Block> for Runtime {
fn configuration() -> sp_consensus_babe::BabeConfiguration {
unimplemented!()
}
fn current_epoch_start() -> sp_consensus_babe::Slot {
unimplemented!()
}
fn current_epoch() -> sp_consensus_babe::Epoch {
unimplemented!()
}
fn next_epoch() -> sp_consensus_babe::Epoch {
unimplemented!()
}
fn generate_key_ownership_proof(
_: sp_consensus_babe::Slot,
_: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
unimplemented!()
}
fn submit_report_equivocation_unsigned_extrinsic(
_: sp_consensus_babe::EquivocationProof<<Block as BlockT>::Header>,
_: sp_consensus_babe::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!()
}
}
impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<AuthorityDiscoveryId> {
unimplemented!()
}
}
impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(_: Option<Vec<u8>>) -> Vec<u8> {
unimplemented!()
}
fn decode_session_keys(
_: Vec<u8>,
) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
unimplemented!()
}
}
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
fn account_nonce(_: AccountId) -> Nonce {
unimplemented!()
}
}
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Block,
Balance,
> for Runtime {
fn query_info(_: <Block as BlockT>::Extrinsic, _: u32) -> RuntimeDispatchInfo<Balance> {
unimplemented!()
}
fn query_fee_details(_: <Block as BlockT>::Extrinsic, _: u32) -> FeeDetails<Balance> {
unimplemented!()
}
fn query_weight_to_fee(_: Weight) -> Balance {
unimplemented!()
}
fn query_length_to_fee(_: u32) -> Balance {
unimplemented!()
}
}
impl crate::fake_runtime_api::GetLastTimestamp<Block> for Runtime {
fn get_last_timestamp() -> u64 {
unimplemented!()
}
}
}
+112 -281
View File
@@ -18,7 +18,15 @@
#![deny(unused_results)]
#[cfg(any(
feature = "polkadot-native",
feature = "kusama-native",
feature = "westend-native",
feature = "rococo-native"
))]
pub mod benchmarking;
pub mod chain_spec;
mod fake_runtime_api;
mod grandpa_support;
mod parachains_db;
mod relay_chain_selection;
@@ -80,34 +88,15 @@ use telemetry::TelemetryWorker;
#[cfg(feature = "full-node")]
use telemetry::{Telemetry, TelemetryWorkerHandle};
#[cfg(feature = "rococo-native")]
pub use polkadot_client::RococoExecutorDispatch;
#[cfg(feature = "westend-native")]
pub use polkadot_client::WestendExecutorDispatch;
#[cfg(feature = "kusama-native")]
pub use polkadot_client::KusamaExecutorDispatch;
#[cfg(feature = "polkadot-native")]
pub use polkadot_client::PolkadotExecutorDispatch;
pub use chain_spec::{KusamaChainSpec, PolkadotChainSpec, RococoChainSpec, WestendChainSpec};
pub use consensus_common::{block_validation::Chain, Proposal, SelectChain};
pub use consensus_common::{Proposal, SelectChain};
use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE;
use mmr_gadget::MmrGadget;
#[cfg(feature = "full-node")]
pub use polkadot_client::{
AbstractClient, Client, ClientHandle, ExecuteWithClient, FullBackend, FullClient,
RuntimeApiCollection,
};
pub use polkadot_primitives::{Block, BlockId, BlockNumber, CollatorPair, Hash, Id as ParaId};
pub use sc_client_api::{Backend, CallExecutor, ExecutionStrategy};
pub use sc_consensus::{BlockImport, LongestChain};
pub use sc_executor::NativeExecutionDispatch;
use sc_executor::{
HeapAllocStrategy, NativeElseWasmExecutor, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY,
};
use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY};
pub use service::{
config::{DatabaseSource, PrometheusConfig},
ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role, RuntimeGenesis,
@@ -130,6 +119,18 @@ pub use {rococo_runtime, rococo_runtime_constants};
#[cfg(feature = "westend-native")]
pub use {westend_runtime, westend_runtime_constants};
pub use fake_runtime_api::{GetLastTimestamp, RuntimeApi};
#[cfg(feature = "full-node")]
pub type FullBackend = service::TFullBackend<Block>;
#[cfg(feature = "full-node")]
pub type FullClient = service::TFullClient<
Block,
RuntimeApi,
WasmExecutor<(sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions)>,
>;
/// Provides the header and block number for a hash.
///
/// Decouples `sc_client_api::Backend` and `sp_blockchain::HeaderBackend`.
@@ -239,6 +240,21 @@ pub enum Error {
NoRuntime,
}
/// Identifies the variant of the chain.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Chain {
/// Polkadot.
Polkadot,
/// Kusama.
Kusama,
/// Rococo or one of its derivations.
Rococo,
/// Westend.
Westend,
/// Unknown chain?
Unknown,
}
/// Can be called for a `Configuration` to identify which network the configuration targets.
pub trait IdentifyVariant {
/// Returns if this is a configuration for the `Polkadot` network.
@@ -261,6 +277,9 @@ pub trait IdentifyVariant {
/// Returns true if this configuration is for a development network.
fn is_dev(&self) -> bool;
/// Identifies the variant of the chain.
fn identify_chain(&self) -> Chain;
}
impl IdentifyVariant for Box<dyn ChainSpec> {
@@ -285,6 +304,19 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
fn is_dev(&self) -> bool {
self.id().ends_with("dev")
}
fn identify_chain(&self) -> Chain {
if self.is_polkadot() {
Chain::Polkadot
} else if self.is_kusama() {
Chain::Kusama
} else if self.is_westend() {
Chain::Westend
} else if self.is_rococo() || self.is_versi() || self.is_wococo() {
Chain::Rococo
} else {
Chain::Unknown
}
}
}
#[cfg(feature = "full-node")]
@@ -340,55 +372,27 @@ fn jaeger_launch_collector_with_agent(
#[cfg(feature = "full-node")]
type FullSelectChain = relay_chain_selection::SelectRelayChain<FullBackend>;
#[cfg(feature = "full-node")]
type FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch, ChainSelection = FullSelectChain> =
grandpa::GrandpaBlockImport<
FullBackend,
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
ChainSelection,
>;
type FullGrandpaBlockImport<ChainSelection = FullSelectChain> =
grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, ChainSelection>;
#[cfg(feature = "full-node")]
type FullBeefyBlockImport<RuntimeApi, ExecutorDispatch, InnerBlockImport> =
beefy::import::BeefyBlockImport<
Block,
FullBackend,
FullClient<RuntimeApi, ExecutorDispatch>,
InnerBlockImport,
>;
type FullBeefyBlockImport<InnerBlockImport> =
beefy::import::BeefyBlockImport<Block, FullBackend, FullClient, InnerBlockImport>;
#[cfg(feature = "full-node")]
struct Basics<RuntimeApi, ExecutorDispatch>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
struct Basics {
task_manager: TaskManager,
client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
client: Arc<FullClient>,
backend: Arc<FullBackend>,
keystore_container: KeystoreContainer,
telemetry: Option<Telemetry>,
}
#[cfg(feature = "full-node")]
fn new_partial_basics<RuntimeApi, ExecutorDispatch>(
fn new_partial_basics(
config: &mut Configuration,
jaeger_agent: Option<std::net::SocketAddr>,
telemetry_worker_handle: Option<TelemetryWorkerHandle>,
) -> Result<Basics<RuntimeApi, ExecutorDispatch>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
) -> Result<Basics, Error> {
let telemetry = config
.telemetry_endpoints
.clone()
@@ -410,7 +414,7 @@ where
.default_heap_pages
.map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static { extra_pages: h as _ });
let wasm = WasmExecutor::builder()
let executor = WasmExecutor::builder()
.with_execution_method(config.wasm_method)
.with_onchain_heap_alloc_strategy(heap_pages)
.with_offchain_heap_alloc_strategy(heap_pages)
@@ -418,8 +422,6 @@ where
.with_runtime_cache_size(config.runtime_cache_size)
.build();
let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new_with_wasm_executor(wasm);
let (client, backend, keystore_container, task_manager) =
service::new_full_parts::<Block, RuntimeApi, _>(
&config,
@@ -445,20 +447,17 @@ where
}
#[cfg(feature = "full-node")]
fn new_partial<RuntimeApi, ExecutorDispatch, ChainSelection>(
fn new_partial<ChainSelection>(
config: &mut Configuration,
Basics { task_manager, backend, client, keystore_container, telemetry }: Basics<
RuntimeApi,
ExecutorDispatch,
>,
Basics { task_manager, backend, client, keystore_container, telemetry }: Basics,
select_chain: ChainSelection,
) -> Result<
service::PartialComponents<
FullClient<RuntimeApi, ExecutorDispatch>,
FullClient,
FullBackend,
ChainSelection,
sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
sc_consensus::DefaultImportQueue<Block, FullClient>,
sc_transaction_pool::FullPool<Block, FullClient>,
(
impl Fn(
polkadot_rpc::DenyUnsafe,
@@ -467,14 +466,10 @@ fn new_partial<RuntimeApi, ExecutorDispatch, ChainSelection>(
(
babe::BabeBlockImport<
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
FullBeefyBlockImport<
RuntimeApi,
ExecutorDispatch,
FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch, ChainSelection>,
>,
FullClient,
FullBeefyBlockImport<FullGrandpaBlockImport<ChainSelection>>,
>,
grandpa::LinkHalf<Block, FullClient<RuntimeApi, ExecutorDispatch>, ChainSelection>,
grandpa::LinkHalf<Block, FullClient, ChainSelection>,
babe::BabeLink<Block>,
beefy::BeefyVoterLinks<Block>,
),
@@ -486,13 +481,6 @@ fn new_partial<RuntimeApi, ExecutorDispatch, ChainSelection>(
Error,
>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
ChainSelection: 'static + SelectChain<Block>,
{
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
@@ -616,9 +604,9 @@ where
}
#[cfg(feature = "full-node")]
pub struct NewFull<C> {
pub struct NewFull {
pub task_manager: TaskManager,
pub client: C,
pub client: Arc<FullClient>,
pub overseer_handle: Option<Handle>,
pub network: Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
pub sync_service: Arc<sc_network_sync::SyncingService<Block>>,
@@ -626,22 +614,6 @@ pub struct NewFull<C> {
pub backend: Arc<FullBackend>,
}
#[cfg(feature = "full-node")]
impl<C> NewFull<C> {
/// Convert the client type using the given `func`.
pub fn with_client<NC>(self, func: impl FnOnce(C) -> NC) -> NewFull<NC> {
NewFull {
client: func(self.client),
task_manager: self.task_manager,
overseer_handle: self.overseer_handle,
network: self.network,
sync_service: self.sync_service,
rpc_handlers: self.rpc_handlers,
backend: self.backend,
}
}
}
/// Is this node a collator?
#[cfg(feature = "full-node")]
#[derive(Clone)]
@@ -685,7 +657,7 @@ pub const AVAILABILITY_CONFIG: AvailabilityConfig = AvailabilityConfig {
/// regardless of the role the node has. The relay chain selection (longest or disputes-aware) is
/// still determined based on the role of the node. Likewise for authority discovery.
#[cfg(feature = "full-node")]
pub fn new_full<RuntimeApi, ExecutorDispatch, OverseerGenerator>(
pub fn new_full<OverseerGenerator>(
mut config: Configuration,
is_collator: IsCollator,
grandpa_pause: Option<(u32, u32)>,
@@ -698,15 +670,8 @@ pub fn new_full<RuntimeApi, ExecutorDispatch, OverseerGenerator>(
overseer_message_channel_capacity_override: Option<usize>,
_malus_finality_delay: Option<u32>,
hwbench: Option<sc_sysinfo::HwBench>,
) -> Result<NewFull<Arc<FullClient<RuntimeApi, ExecutorDispatch>>>, Error>
) -> Result<NewFull, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
OverseerGenerator: OverseerGen,
{
use polkadot_node_network_protocol::request_response::IncomingRequest;
@@ -743,11 +708,7 @@ where
let disable_grandpa = config.disable_grandpa;
let name = config.network.node_name.clone();
let basics = new_partial_basics::<RuntimeApi, ExecutorDispatch>(
&mut config,
jaeger_agent,
telemetry_worker_handle,
)?;
let basics = new_partial_basics(&mut config, jaeger_agent, telemetry_worker_handle)?;
let prometheus_registry = config.prometheus_registry().cloned();
@@ -783,11 +744,7 @@ where
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
} = new_partial::<RuntimeApi, ExecutorDispatch, SelectRelayChain<_>>(
&mut config,
basics,
select_chain,
)?;
} = new_partial::<SelectRelayChain<_>>(&mut config, basics, select_chain)?;
let shared_voter_state = rpc_setup;
let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
@@ -1003,7 +960,7 @@ where
let overseer_handle = if let Some(authority_discovery_service) = authority_discovery_service {
let (overseer, overseer_handle) = overseer_gen
.generate::<service::SpawnTaskHandle, FullClient<RuntimeApi, ExecutorDispatch>>(
.generate::<service::SpawnTaskHandle, FullClient>(
overseer_connector,
OverseerGenArgs {
keystore,
@@ -1259,27 +1216,19 @@ where
#[cfg(feature = "full-node")]
macro_rules! chain_ops {
($config:expr, $jaeger_agent:expr, $telemetry_worker_handle:expr; $scope:ident, $executor:ident, $variant:ident) => {{
($config:expr, $jaeger_agent:expr, $telemetry_worker_handle:expr) => {{
let telemetry_worker_handle = $telemetry_worker_handle;
let jaeger_agent = $jaeger_agent;
let mut config = $config;
let basics = new_partial_basics::<$scope::RuntimeApi, $executor>(
config,
jaeger_agent,
telemetry_worker_handle,
)?;
let basics = new_partial_basics(config, jaeger_agent, telemetry_worker_handle)?;
use ::sc_consensus::LongestChain;
// use the longest chain selection, since there is no overseer available
let chain_selection = LongestChain::new(basics.backend.clone());
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<$scope::RuntimeApi, $executor, LongestChain<_, Block>>(
&mut config,
basics,
chain_selection,
)?;
Ok((Arc::new(Client::$variant(client)), backend, import_queue, task_manager))
new_partial::<LongestChain<_, Block>>(&mut config, basics, chain_selection)?;
Ok((client, backend, import_queue, task_manager))
}};
}
@@ -1290,7 +1239,7 @@ pub fn new_chain_ops(
jaeger_agent: Option<std::net::SocketAddr>,
) -> Result<
(
Arc<Client>,
Arc<FullClient>,
Arc<FullBackend>,
sc_consensus::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
TaskManager,
@@ -1299,35 +1248,17 @@ pub fn new_chain_ops(
> {
config.keystore = service::config::KeystoreConfig::InMemory;
#[cfg(feature = "rococo-native")]
if config.chain_spec.is_rococo() ||
config.chain_spec.is_wococo() ||
config.chain_spec.is_versi()
{
return chain_ops!(config, jaeger_agent, None; rococo_runtime, RococoExecutorDispatch, Rococo)
}
#[cfg(feature = "kusama-native")]
if config.chain_spec.is_kusama() {
return chain_ops!(config, jaeger_agent, None; kusama_runtime, KusamaExecutorDispatch, Kusama)
}
#[cfg(feature = "westend-native")]
if config.chain_spec.is_westend() {
return chain_ops!(config, jaeger_agent, None; westend_runtime, WestendExecutorDispatch, Westend)
}
#[cfg(feature = "polkadot-native")]
{
return chain_ops!(config, jaeger_agent, None; polkadot_runtime, PolkadotExecutorDispatch, Polkadot)
}
#[cfg(not(feature = "polkadot-native"))]
{
let _ = config;
let _ = jaeger_agent;
Err(Error::NoRuntime)
chain_ops!(config, jaeger_agent, None)
} else if config.chain_spec.is_kusama() {
chain_ops!(config, jaeger_agent, None)
} else if config.chain_spec.is_westend() {
return chain_ops!(config, jaeger_agent, None)
} else {
chain_ops!(config, jaeger_agent, None)
}
}
@@ -1352,105 +1283,28 @@ pub fn build_full(
overseer_message_channel_override: Option<usize>,
malus_finality_delay: Option<u32>,
hwbench: Option<sc_sysinfo::HwBench>,
) -> Result<NewFull<Client>, Error> {
#[cfg(feature = "rococo-native")]
if config.chain_spec.is_rococo() ||
config.chain_spec.is_wococo() ||
config.chain_spec.is_versi()
{
return new_full::<rococo_runtime::RuntimeApi, RococoExecutorDispatch, _>(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
None,
overseer_enable_anyways,
overseer_gen,
overseer_message_channel_override,
malus_finality_delay,
hwbench,
)
.map(|full| full.with_client(Client::Rococo))
}
) -> Result<NewFull, Error> {
let is_polkadot = config.chain_spec.is_polkadot();
#[cfg(feature = "kusama-native")]
if config.chain_spec.is_kusama() {
return new_full::<kusama_runtime::RuntimeApi, KusamaExecutorDispatch, _>(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
None,
overseer_enable_anyways,
overseer_gen,
overseer_message_channel_override,
malus_finality_delay,
hwbench,
)
.map(|full| full.with_client(Client::Kusama))
}
#[cfg(feature = "westend-native")]
if config.chain_spec.is_westend() {
return new_full::<westend_runtime::RuntimeApi, WestendExecutorDispatch, _>(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
None,
overseer_enable_anyways,
overseer_gen,
overseer_message_channel_override,
malus_finality_delay,
hwbench,
)
.map(|full| full.with_client(Client::Westend))
}
#[cfg(feature = "polkadot-native")]
{
return new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutorDispatch, _>(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
None,
overseer_enable_anyways,
overseer_gen,
overseer_message_channel_override.map(|capacity| {
new_full(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
None,
overseer_enable_anyways,
overseer_gen,
overseer_message_channel_override.map(move |capacity| {
if is_polkadot {
gum::warn!("Channel capacity should _never_ be tampered with on polkadot!");
capacity
}),
malus_finality_delay,
hwbench,
)
.map(|full| full.with_client(Client::Polkadot))
}
#[cfg(not(feature = "polkadot-native"))]
{
let _ = config;
let _ = is_collator;
let _ = grandpa_pause;
let _ = enable_beefy;
let _ = jaeger_agent;
let _ = telemetry_worker_handle;
let _ = overseer_enable_anyways;
let _ = overseer_gen;
let _ = overseer_message_channel_override;
let _ = malus_finality_delay;
let _ = hwbench;
Err(Error::NoRuntime)
}
}
capacity
}),
malus_finality_delay,
hwbench,
)
}
/// Reverts the node state down to at most the last finalized block.
@@ -1461,7 +1315,7 @@ pub fn build_full(
/// - Low level Babe and Grandpa consensus data.
#[cfg(feature = "full-node")]
pub fn revert_backend(
client: Arc<Client>,
client: Arc<FullClient>,
backend: Arc<FullBackend>,
blocks: BlockNumber,
config: Configuration,
@@ -1488,7 +1342,8 @@ pub fn revert_backend(
revert_approval_voting(parachains_db.clone(), hash)?;
revert_chain_selection(parachains_db, hash)?;
// Revert Substrate consensus related components
client.execute_with(RevertConsensus { blocks, backend })?;
babe::revert(client.clone(), backend, blocks)?;
grandpa::revert(client, blocks)?;
Ok(())
}
@@ -1525,27 +1380,3 @@ fn revert_approval_voting(db: Arc<dyn Database>, hash: Hash) -> sp_blockchain::R
.revert_to(hash)
.map_err(|err| sp_blockchain::Error::Backend(err.to_string()))
}
struct RevertConsensus {
blocks: BlockNumber,
backend: Arc<FullBackend>,
}
impl ExecuteWithClient for RevertConsensus {
type Output = sp_blockchain::Result<()>;
fn execute_with_client<Client, Api, Backend>(self, client: Arc<Client>) -> Self::Output
where
<Api as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
Backend: sc_client_api::Backend<Block> + 'static,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Api: polkadot_client::RuntimeApiCollection<StateBackend = Backend::State>,
Client: AbstractClient<Block, Backend, Api = Api> + 'static,
{
// Revert consensus-related components.
// The operations are not correlated, thus call order is not relevant.
babe::revert(client.clone(), self.backend, self.blocks)?;
grandpa::revert(client, self.blocks)?;
Ok(())
}
}