mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-18 15:21:05 +00:00
Aura consensus for parachains (#371)
* Update polkadot * Migrate all uses of MQC heads to merkle proofs * Mass rename `relay_parent_storage_root` * Restore parachain-system tests * Update polkadot and libp2p swarm for testing * Collapse match into an if let Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Start with something * Update Substrate & Polkadot * Start to make it compile * Make it compile * Begin with something * Yep * I'm a hacker * Bring back the builder * Make it work in some way * Compile * Parachains use their own "slot" * Adds cumulus-pallet-aura * Wrap AuRa import queue to disable equivocation checking by default * Pass slot duration * Check the seal when validating a block * Adds missing file * Try to make the seal working * Fix it * Some fixes * Bring in the latest features to cleanup the code * Update and make it compile * Improve the import * Start fixing * More work * Fix fix fix * Make everything compile * Small cleanups * Rename and more docs * Docs * Fixes fixes fixes * Update rococo-parachains/src/chain_spec.rs * Update client/consensus/aura/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/aura/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update primitives/parachain-inherent/Cargo.toml Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update primitives/parachain-inherent/Cargo.toml * Update primitives/parachain-inherent/Cargo.toml * Update primitives/parachain-inherent/Cargo.toml Co-authored-by: Sergei Shulepov <sergei@parity.io> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Generated
+339
-206
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"client/cli",
|
"client/cli",
|
||||||
|
"client/consensus/aura",
|
||||||
"client/consensus/common",
|
"client/consensus/common",
|
||||||
"client/consensus/relay-chain",
|
"client/consensus/relay-chain",
|
||||||
"client/network",
|
"client/network",
|
||||||
"client/service",
|
"client/service",
|
||||||
|
"pallets/aura-ext",
|
||||||
"pallets/dmp-queue",
|
"pallets/dmp-queue",
|
||||||
"pallets/parachain-system",
|
"pallets/parachain-system",
|
||||||
"pallets/xcm",
|
"pallets/xcm",
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
[package]
|
||||||
|
name = "cumulus-client-consensus-aura"
|
||||||
|
description = "AURA consensus algorithm for parachains"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Substrate dependencies
|
||||||
|
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
|
# Polkadot dependencies
|
||||||
|
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||||
|
|
||||||
|
# Cumulus dependencies
|
||||||
|
cumulus-client-consensus-common = { path = "../common" }
|
||||||
|
cumulus-primitives-core = { path = "../../../primitives/core" }
|
||||||
|
|
||||||
|
# Other deps
|
||||||
|
futures = { version = "0.3.8", features = ["compat"] }
|
||||||
|
codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] }
|
||||||
|
tracing = "0.1.22"
|
||||||
|
async-trait = "0.1.42"
|
||||||
|
parking_lot = "0.9"
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Cumulus.
|
||||||
|
|
||||||
|
// Cumulus is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Cumulus is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Parachain specific wrapper for the AuRa import queue.
|
||||||
|
|
||||||
|
use codec::Codec;
|
||||||
|
use sc_client_api::{backend::AuxStore, BlockOf};
|
||||||
|
use sc_consensus_slots::InherentDataProviderExt;
|
||||||
|
use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||||
|
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||||
|
use sp_blockchain::{HeaderBackend, ProvideCache};
|
||||||
|
use sp_consensus::{
|
||||||
|
import_queue::DefaultImportQueue, BlockImport, CanAuthorWith, Error as ConsensusError,
|
||||||
|
};
|
||||||
|
use sp_consensus_aura::{digests::CompatibleDigestItem, AuraApi};
|
||||||
|
use sp_core::crypto::Pair;
|
||||||
|
use sp_inherents::CreateInherentDataProviders;
|
||||||
|
use sp_runtime::traits::{Block as BlockT, DigestItemFor};
|
||||||
|
use std::{fmt::Debug, hash::Hash, sync::Arc};
|
||||||
|
use substrate_prometheus_endpoint::Registry;
|
||||||
|
use sc_telemetry::TelemetryHandle;
|
||||||
|
|
||||||
|
/// Parameters of [`import_queue`].
|
||||||
|
pub struct ImportQueueParams<'a, I, C, IDP, S, CAW> {
|
||||||
|
/// The block import to use.
|
||||||
|
pub block_import: I,
|
||||||
|
/// The client to interact with the chain.
|
||||||
|
pub client: Arc<C>,
|
||||||
|
/// The inherent data providers, to create the inherent data.
|
||||||
|
pub create_inherent_data_providers: IDP,
|
||||||
|
/// The spawner to spawn background tasks.
|
||||||
|
pub spawner: &'a S,
|
||||||
|
/// The prometheus registry.
|
||||||
|
pub registry: Option<&'a Registry>,
|
||||||
|
/// Can we author with the current node?
|
||||||
|
pub can_author_with: CAW,
|
||||||
|
/// The telemetry handle.
|
||||||
|
pub telemetry: Option<TelemetryHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an import queue for the Aura consensus algorithm.
|
||||||
|
pub fn import_queue<'a, P, Block, I, C, S, CAW, IDP>(
|
||||||
|
ImportQueueParams {
|
||||||
|
block_import,
|
||||||
|
client,
|
||||||
|
create_inherent_data_providers,
|
||||||
|
spawner,
|
||||||
|
registry,
|
||||||
|
can_author_with,
|
||||||
|
telemetry,
|
||||||
|
}: ImportQueueParams<'a, I, C, IDP, S, CAW>,
|
||||||
|
) -> Result<DefaultImportQueue<Block, C>, sp_consensus::Error>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
C::Api: BlockBuilderApi<Block> + AuraApi<Block, P::Public> + ApiExt<Block>,
|
||||||
|
C: 'static
|
||||||
|
+ ProvideRuntimeApi<Block>
|
||||||
|
+ BlockOf
|
||||||
|
+ ProvideCache<Block>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderBackend<Block>,
|
||||||
|
I: BlockImport<Block, Error = ConsensusError, Transaction = sp_api::TransactionFor<C, Block>>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
DigestItemFor<Block>: CompatibleDigestItem<P::Signature>,
|
||||||
|
P: Pair + Send + Sync + 'static,
|
||||||
|
P::Public: Clone + Eq + Send + Sync + Hash + Debug + Codec,
|
||||||
|
P::Signature: Codec,
|
||||||
|
S: sp_core::traits::SpawnEssentialNamed,
|
||||||
|
CAW: CanAuthorWith<Block> + Send + Sync + 'static,
|
||||||
|
IDP: CreateInherentDataProviders<Block, ()> + Sync + Send + 'static,
|
||||||
|
IDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
|
||||||
|
{
|
||||||
|
sc_consensus_aura::import_queue::<P, _, _, _, _, _, _>(sc_consensus_aura::ImportQueueParams {
|
||||||
|
block_import: crate::ParachainBlockImport(block_import),
|
||||||
|
justification_import: None,
|
||||||
|
client,
|
||||||
|
create_inherent_data_providers,
|
||||||
|
spawner,
|
||||||
|
registry,
|
||||||
|
can_author_with,
|
||||||
|
check_for_equivocation: sc_consensus_aura::CheckForEquivocation::No,
|
||||||
|
telemetry,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Cumulus.
|
||||||
|
|
||||||
|
// Cumulus is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Cumulus is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! The AuRa consensus algoritm for parachains.
|
||||||
|
//!
|
||||||
|
//! This extends the Substrate provided AuRa consensus implementation to make it compatible for
|
||||||
|
//! parachains. The main entry points for of this consensus algorithm are [`build_aura_consensus`]
|
||||||
|
//! and [`import_queue`].
|
||||||
|
//!
|
||||||
|
//! For more information about AuRa, the Substrate crate should be checked.
|
||||||
|
|
||||||
|
use codec::{Decode, Encode};
|
||||||
|
use cumulus_client_consensus_common::{ParachainCandidate, ParachainConsensus};
|
||||||
|
use cumulus_primitives_core::{
|
||||||
|
relay_chain::v1::{Block as PBlock, Hash as PHash, ParachainHost},
|
||||||
|
PersistedValidationData,
|
||||||
|
};
|
||||||
|
use futures::lock::Mutex;
|
||||||
|
use polkadot_service::ClientHandle;
|
||||||
|
use sc_client_api::{backend::AuxStore, Backend, BlockOf};
|
||||||
|
use sc_consensus_slots::{BackoffAuthoringBlocksStrategy, SlotInfo};
|
||||||
|
use sc_telemetry::TelemetryHandle;
|
||||||
|
use sp_api::ProvideRuntimeApi;
|
||||||
|
use sp_application_crypto::AppPublic;
|
||||||
|
use sp_blockchain::{HeaderBackend, ProvideCache};
|
||||||
|
use sp_consensus::{
|
||||||
|
BlockImport, EnableProofRecording, Environment, ProofRecording, Proposer, SlotData, SyncOracle,
|
||||||
|
};
|
||||||
|
use sp_consensus_aura::AuraApi;
|
||||||
|
use sp_core::crypto::Pair;
|
||||||
|
use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider};
|
||||||
|
use sp_keystore::SyncCryptoStorePtr;
|
||||||
|
use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT, Member, NumberFor};
|
||||||
|
use std::{convert::TryFrom, hash::Hash, marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
|
mod import_queue;
|
||||||
|
|
||||||
|
pub use import_queue::{import_queue, ImportQueueParams};
|
||||||
|
pub use sc_consensus_aura::{
|
||||||
|
slot_duration, AuraBlockImport, BuildAuraWorkerParams, SlotDuration, SlotProportion,
|
||||||
|
};
|
||||||
|
pub use sc_consensus_slots::InherentDataProviderExt;
|
||||||
|
|
||||||
|
const LOG_TARGET: &str = "aura::cumulus";
|
||||||
|
|
||||||
|
/// The implementation of the AURA consensus for parachains.
|
||||||
|
pub struct AuraConsensus<B, RClient, RBackend, CIDP> {
|
||||||
|
create_inherent_data_providers: Arc<CIDP>,
|
||||||
|
relay_chain_client: Arc<RClient>,
|
||||||
|
relay_chain_backend: Arc<RBackend>,
|
||||||
|
aura_worker: Arc<
|
||||||
|
Mutex<
|
||||||
|
dyn sc_consensus_slots::SlotWorker<B, <EnableProofRecording as ProofRecording>::Proof>
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
slot_duration: SlotDuration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B, RClient, RBackend, CIDP> Clone for AuraConsensus<B, RClient, RBackend, CIDP> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
create_inherent_data_providers: self.create_inherent_data_providers.clone(),
|
||||||
|
relay_chain_backend: self.relay_chain_backend.clone(),
|
||||||
|
relay_chain_client: self.relay_chain_client.clone(),
|
||||||
|
aura_worker: self.aura_worker.clone(),
|
||||||
|
slot_duration: self.slot_duration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B, RClient, RBackend, CIDP> AuraConsensus<B, RClient, RBackend, CIDP>
|
||||||
|
where
|
||||||
|
B: BlockT,
|
||||||
|
RClient: ProvideRuntimeApi<PBlock>,
|
||||||
|
RClient::Api: ParachainHost<PBlock>,
|
||||||
|
RBackend: Backend<PBlock>,
|
||||||
|
CIDP: CreateInherentDataProviders<B, (PHash, PersistedValidationData)>,
|
||||||
|
CIDP::InherentDataProviders: InherentDataProviderExt,
|
||||||
|
{
|
||||||
|
/// Create a new instance of AURA consensus.
|
||||||
|
pub fn new<P, Client, BI, SO, PF, BS, Error>(
|
||||||
|
para_client: Arc<Client>,
|
||||||
|
block_import: BI,
|
||||||
|
sync_oracle: SO,
|
||||||
|
proposer_factory: PF,
|
||||||
|
force_authoring: bool,
|
||||||
|
backoff_authoring_blocks: Option<BS>,
|
||||||
|
keystore: SyncCryptoStorePtr,
|
||||||
|
create_inherent_data_providers: CIDP,
|
||||||
|
polkadot_client: Arc<RClient>,
|
||||||
|
polkadot_backend: Arc<RBackend>,
|
||||||
|
slot_duration: SlotDuration,
|
||||||
|
telemetry: Option<TelemetryHandle>,
|
||||||
|
block_proposal_slot_portion: SlotProportion,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Client: ProvideRuntimeApi<B>
|
||||||
|
+ BlockOf
|
||||||
|
+ ProvideCache<B>
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderBackend<B>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
Client::Api: AuraApi<B, P::Public>,
|
||||||
|
BI: BlockImport<B, Transaction = sp_api::TransactionFor<Client, B>> + Send + Sync + 'static,
|
||||||
|
SO: SyncOracle + Send + Sync + Clone + 'static,
|
||||||
|
BS: BackoffAuthoringBlocksStrategy<NumberFor<B>> + Send + 'static,
|
||||||
|
PF: Environment<B, Error = Error> + Send + Sync + 'static,
|
||||||
|
PF::Proposer: Proposer<
|
||||||
|
B,
|
||||||
|
Error = Error,
|
||||||
|
Transaction = sp_api::TransactionFor<Client, B>,
|
||||||
|
ProofRecording = EnableProofRecording,
|
||||||
|
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
||||||
|
>,
|
||||||
|
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||||
|
P: Pair + Send + Sync,
|
||||||
|
P::Public: AppPublic + Hash + Member + Encode + Decode,
|
||||||
|
P::Signature: TryFrom<Vec<u8>> + Hash + Member + Encode + Decode,
|
||||||
|
{
|
||||||
|
let worker =
|
||||||
|
sc_consensus_aura::build_aura_worker::<P, _, _, _, _, _, _, _>(BuildAuraWorkerParams {
|
||||||
|
client: para_client,
|
||||||
|
block_import: ParachainBlockImport(block_import),
|
||||||
|
proposer_factory,
|
||||||
|
sync_oracle,
|
||||||
|
force_authoring,
|
||||||
|
backoff_authoring_blocks,
|
||||||
|
keystore,
|
||||||
|
telemetry,
|
||||||
|
block_proposal_slot_portion,
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
create_inherent_data_providers: Arc::new(create_inherent_data_providers),
|
||||||
|
relay_chain_backend: polkadot_backend,
|
||||||
|
relay_chain_client: polkadot_client,
|
||||||
|
aura_worker: Arc::new(Mutex::new(worker)),
|
||||||
|
slot_duration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create the inherent data.
|
||||||
|
///
|
||||||
|
/// Returns the created inherent data and the inherent data providers used.
|
||||||
|
async fn inherent_data(
|
||||||
|
&self,
|
||||||
|
parent: B::Hash,
|
||||||
|
validation_data: &PersistedValidationData,
|
||||||
|
relay_parent: PHash,
|
||||||
|
) -> Option<(InherentData, CIDP::InherentDataProviders)> {
|
||||||
|
let inherent_data_providers = self
|
||||||
|
.create_inherent_data_providers
|
||||||
|
.create_inherent_data_providers(parent, (relay_parent, validation_data.clone()))
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Failed to create inherent data providers.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
inherent_data_providers
|
||||||
|
.create_inherent_data()
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
error = ?e,
|
||||||
|
"Failed to create inherent data.",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.map(|d| (d, inherent_data_providers))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl<B, RClient, RBackend, CIDP> ParachainConsensus<B> for AuraConsensus<B, RClient, RBackend, CIDP>
|
||||||
|
where
|
||||||
|
B: BlockT,
|
||||||
|
RClient: ProvideRuntimeApi<PBlock> + Send + Sync,
|
||||||
|
RClient::Api: ParachainHost<PBlock>,
|
||||||
|
RBackend: Backend<PBlock>,
|
||||||
|
CIDP: CreateInherentDataProviders<B, (PHash, PersistedValidationData)> + Send + Sync,
|
||||||
|
CIDP::InherentDataProviders: InherentDataProviderExt + Send,
|
||||||
|
{
|
||||||
|
async fn produce_candidate(
|
||||||
|
&mut self,
|
||||||
|
parent: &B::Header,
|
||||||
|
relay_parent: PHash,
|
||||||
|
validation_data: &PersistedValidationData,
|
||||||
|
) -> Option<ParachainCandidate<B>> {
|
||||||
|
let (inherent_data, inherent_data_providers) = self
|
||||||
|
.inherent_data(parent.hash(), validation_data, relay_parent)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let info = SlotInfo::new(
|
||||||
|
inherent_data_providers.slot(),
|
||||||
|
inherent_data_providers.timestamp(),
|
||||||
|
inherent_data,
|
||||||
|
self.slot_duration.slot_duration(),
|
||||||
|
parent.clone(),
|
||||||
|
// Set the block limit to 50% of the maximum PoV size.
|
||||||
|
//
|
||||||
|
// TODO: If we got benchmarking that includes the proof size,
|
||||||
|
// we should be able to use the maximum pov size.
|
||||||
|
Some((validation_data.max_pov_size / 2) as usize),
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = self.aura_worker.lock().await.on_slot(info).await?;
|
||||||
|
|
||||||
|
Some(ParachainCandidate {
|
||||||
|
block: res.block,
|
||||||
|
proof: res.storage_proof,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parachain specific block import.
|
||||||
|
///
|
||||||
|
/// This is used to set `block_import_params.fork_choice` to `false` as long as the block origin is
|
||||||
|
/// not `NetworkInitialSync`. The best block for parachains is determined by the relay chain. Meaning
|
||||||
|
/// we will update the best block, as it is included by the relay-chain.
|
||||||
|
struct ParachainBlockImport<I>(I);
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl<Block, I> BlockImport<Block> for ParachainBlockImport<I>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
I: BlockImport<Block> + Send,
|
||||||
|
{
|
||||||
|
type Error = I::Error;
|
||||||
|
type Transaction = I::Transaction;
|
||||||
|
|
||||||
|
async fn check_block(
|
||||||
|
&mut self,
|
||||||
|
block: sp_consensus::BlockCheckParams<Block>,
|
||||||
|
) -> Result<sp_consensus::ImportResult, Self::Error> {
|
||||||
|
self.0.check_block(block).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn import_block(
|
||||||
|
&mut self,
|
||||||
|
mut block_import_params: sp_consensus::BlockImportParams<Block, Self::Transaction>,
|
||||||
|
cache: std::collections::HashMap<sp_consensus::import_queue::CacheKeyId, Vec<u8>>,
|
||||||
|
) -> Result<sp_consensus::ImportResult, Self::Error> {
|
||||||
|
// Best block is determined by the relay chain, or if we are doing the intial sync
|
||||||
|
// we import all blocks as new best.
|
||||||
|
block_import_params.fork_choice = Some(sp_consensus::ForkChoiceStrategy::Custom(
|
||||||
|
block_import_params.origin == sp_consensus::BlockOrigin::NetworkInitialSync,
|
||||||
|
));
|
||||||
|
self.0.import_block(block_import_params, cache).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Paramaters of [`build_aura_consensus`].
|
||||||
|
pub struct BuildAuraConsensusParams<PF, BI, RBackend, CIDP, Client, BS, SO> {
|
||||||
|
pub proposer_factory: PF,
|
||||||
|
pub create_inherent_data_providers: CIDP,
|
||||||
|
pub block_import: BI,
|
||||||
|
pub relay_chain_client: polkadot_service::Client,
|
||||||
|
pub relay_chain_backend: Arc<RBackend>,
|
||||||
|
pub para_client: Arc<Client>,
|
||||||
|
pub backoff_authoring_blocks: Option<BS>,
|
||||||
|
pub sync_oracle: SO,
|
||||||
|
pub keystore: SyncCryptoStorePtr,
|
||||||
|
pub force_authoring: bool,
|
||||||
|
pub slot_duration: SlotDuration,
|
||||||
|
pub telemetry: Option<TelemetryHandle>,
|
||||||
|
pub block_proposal_slot_portion: SlotProportion,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build the [`AuraConsensus`].
|
||||||
|
///
|
||||||
|
/// Returns a boxed [`ParachainConsensus`].
|
||||||
|
pub fn build_aura_consensus<P, Block, PF, BI, RBackend, CIDP, Client, SO, BS, Error>(
|
||||||
|
BuildAuraConsensusParams {
|
||||||
|
proposer_factory,
|
||||||
|
create_inherent_data_providers,
|
||||||
|
block_import,
|
||||||
|
relay_chain_client,
|
||||||
|
relay_chain_backend,
|
||||||
|
para_client,
|
||||||
|
backoff_authoring_blocks,
|
||||||
|
sync_oracle,
|
||||||
|
keystore,
|
||||||
|
force_authoring,
|
||||||
|
slot_duration,
|
||||||
|
telemetry,
|
||||||
|
block_proposal_slot_portion,
|
||||||
|
}: BuildAuraConsensusParams<PF, BI, RBackend, CIDP, Client, BS, SO>,
|
||||||
|
) -> Box<dyn ParachainConsensus<Block>>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
||||||
|
sc_client_api::StateBackendFor<RBackend, PBlock>: sc_client_api::StateBackend<HashFor<PBlock>>,
|
||||||
|
RBackend: Backend<PBlock> + 'static,
|
||||||
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
CIDP::InherentDataProviders: InherentDataProviderExt + Send,
|
||||||
|
Client: ProvideRuntimeApi<Block>
|
||||||
|
+ BlockOf
|
||||||
|
+ ProvideCache<Block>
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderBackend<Block>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
Client::Api: AuraApi<Block, P::Public>,
|
||||||
|
BI: BlockImport<Block, Transaction = sp_api::TransactionFor<Client, Block>>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
SO: SyncOracle + Send + Sync + Clone + 'static,
|
||||||
|
BS: BackoffAuthoringBlocksStrategy<NumberFor<Block>> + Send + 'static,
|
||||||
|
PF: Environment<Block, Error = Error> + Send + Sync + 'static,
|
||||||
|
PF::Proposer: Proposer<
|
||||||
|
Block,
|
||||||
|
Error = Error,
|
||||||
|
Transaction = sp_api::TransactionFor<Client, Block>,
|
||||||
|
ProofRecording = EnableProofRecording,
|
||||||
|
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
||||||
|
>,
|
||||||
|
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||||
|
P: Pair + Send + Sync,
|
||||||
|
P::Public: AppPublic + Hash + Member + Encode + Decode,
|
||||||
|
P::Signature: TryFrom<Vec<u8>> + Hash + Member + Encode + Decode,
|
||||||
|
{
|
||||||
|
AuraConsensusBuilder::<P, _, _, _, _, _, _, _, _, _>::new(
|
||||||
|
proposer_factory,
|
||||||
|
block_import,
|
||||||
|
create_inherent_data_providers,
|
||||||
|
relay_chain_client,
|
||||||
|
relay_chain_backend,
|
||||||
|
para_client,
|
||||||
|
backoff_authoring_blocks,
|
||||||
|
sync_oracle,
|
||||||
|
force_authoring,
|
||||||
|
keystore,
|
||||||
|
slot_duration,
|
||||||
|
telemetry,
|
||||||
|
block_proposal_slot_portion,
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Aura consensus builder.
|
||||||
|
///
|
||||||
|
/// Builds a [`AuraConsensus`] for a parachain. As this requires
|
||||||
|
/// a concrete relay chain client instance, the builder takes a [`polkadot_service::Client`]
|
||||||
|
/// that wraps this concrete instance. By using [`polkadot_service::ExecuteWithClient`]
|
||||||
|
/// the builder gets access to this concrete instance.
|
||||||
|
struct AuraConsensusBuilder<P, Block, PF, BI, RBackend, CIDP, Client, SO, BS, Error> {
|
||||||
|
_phantom: PhantomData<(Block, Error, P)>,
|
||||||
|
proposer_factory: PF,
|
||||||
|
create_inherent_data_providers: CIDP,
|
||||||
|
block_import: BI,
|
||||||
|
relay_chain_backend: Arc<RBackend>,
|
||||||
|
relay_chain_client: polkadot_service::Client,
|
||||||
|
para_client: Arc<Client>,
|
||||||
|
backoff_authoring_blocks: Option<BS>,
|
||||||
|
sync_oracle: SO,
|
||||||
|
force_authoring: bool,
|
||||||
|
keystore: SyncCryptoStorePtr,
|
||||||
|
slot_duration: SlotDuration,
|
||||||
|
telemetry: Option<TelemetryHandle>,
|
||||||
|
block_proposal_slot_portion: SlotProportion,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Block, PF, BI, RBackend, CIDP, Client, SO, BS, P, Error>
|
||||||
|
AuraConsensusBuilder<P, Block, PF, BI, RBackend, CIDP, Client, SO, BS, Error>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
||||||
|
sc_client_api::StateBackendFor<RBackend, PBlock>: sc_client_api::StateBackend<HashFor<PBlock>>,
|
||||||
|
RBackend: Backend<PBlock> + 'static,
|
||||||
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
CIDP::InherentDataProviders: InherentDataProviderExt + Send,
|
||||||
|
Client: ProvideRuntimeApi<Block>
|
||||||
|
+ BlockOf
|
||||||
|
+ ProvideCache<Block>
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderBackend<Block>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
Client::Api: AuraApi<Block, P::Public>,
|
||||||
|
BI: BlockImport<Block, Transaction = sp_api::TransactionFor<Client, Block>>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
SO: SyncOracle + Send + Sync + Clone + 'static,
|
||||||
|
BS: BackoffAuthoringBlocksStrategy<NumberFor<Block>> + Send + 'static,
|
||||||
|
PF: Environment<Block, Error = Error> + Send + Sync + 'static,
|
||||||
|
PF::Proposer: Proposer<
|
||||||
|
Block,
|
||||||
|
Error = Error,
|
||||||
|
Transaction = sp_api::TransactionFor<Client, Block>,
|
||||||
|
ProofRecording = EnableProofRecording,
|
||||||
|
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
||||||
|
>,
|
||||||
|
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||||
|
P: Pair + Send + Sync,
|
||||||
|
P::Public: AppPublic + Hash + Member + Encode + Decode,
|
||||||
|
P::Signature: TryFrom<Vec<u8>> + Hash + Member + Encode + Decode,
|
||||||
|
{
|
||||||
|
/// Create a new instance of the builder.
|
||||||
|
fn new(
|
||||||
|
proposer_factory: PF,
|
||||||
|
block_import: BI,
|
||||||
|
create_inherent_data_providers: CIDP,
|
||||||
|
relay_chain_client: polkadot_service::Client,
|
||||||
|
relay_chain_backend: Arc<RBackend>,
|
||||||
|
para_client: Arc<Client>,
|
||||||
|
backoff_authoring_blocks: Option<BS>,
|
||||||
|
sync_oracle: SO,
|
||||||
|
force_authoring: bool,
|
||||||
|
keystore: SyncCryptoStorePtr,
|
||||||
|
slot_duration: SlotDuration,
|
||||||
|
telemetry: Option<TelemetryHandle>,
|
||||||
|
block_proposal_slot_portion: SlotProportion,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
_phantom: PhantomData,
|
||||||
|
proposer_factory,
|
||||||
|
block_import,
|
||||||
|
create_inherent_data_providers,
|
||||||
|
relay_chain_backend,
|
||||||
|
relay_chain_client,
|
||||||
|
para_client,
|
||||||
|
backoff_authoring_blocks,
|
||||||
|
sync_oracle,
|
||||||
|
force_authoring,
|
||||||
|
keystore,
|
||||||
|
slot_duration,
|
||||||
|
telemetry,
|
||||||
|
block_proposal_slot_portion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build the relay chain consensus.
|
||||||
|
fn build(self) -> Box<dyn ParachainConsensus<Block>> {
|
||||||
|
self.relay_chain_client.clone().execute_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Block, PF, BI, RBackend, CIDP, Client, SO, BS, P, Error> polkadot_service::ExecuteWithClient
|
||||||
|
for AuraConsensusBuilder<P, Block, PF, BI, RBackend, CIDP, Client, SO, BS, Error>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
||||||
|
sc_client_api::StateBackendFor<RBackend, PBlock>: sc_client_api::StateBackend<HashFor<PBlock>>,
|
||||||
|
RBackend: Backend<PBlock> + 'static,
|
||||||
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
CIDP::InherentDataProviders: InherentDataProviderExt + Send,
|
||||||
|
Client: ProvideRuntimeApi<Block>
|
||||||
|
+ BlockOf
|
||||||
|
+ ProvideCache<Block>
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderBackend<Block>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
Client::Api: AuraApi<Block, P::Public>,
|
||||||
|
BI: BlockImport<Block, Transaction = sp_api::TransactionFor<Client, Block>>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
SO: SyncOracle + Send + Sync + Clone + 'static,
|
||||||
|
BS: BackoffAuthoringBlocksStrategy<NumberFor<Block>> + Send + 'static,
|
||||||
|
PF: Environment<Block, Error = Error> + Send + Sync + 'static,
|
||||||
|
PF::Proposer: Proposer<
|
||||||
|
Block,
|
||||||
|
Error = Error,
|
||||||
|
Transaction = sp_api::TransactionFor<Client, Block>,
|
||||||
|
ProofRecording = EnableProofRecording,
|
||||||
|
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
||||||
|
>,
|
||||||
|
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||||
|
P: Pair + Send + Sync,
|
||||||
|
P::Public: AppPublic + Hash + Member + Encode + Decode,
|
||||||
|
P::Signature: TryFrom<Vec<u8>> + Hash + Member + Encode + Decode,
|
||||||
|
{
|
||||||
|
type Output = Box<dyn ParachainConsensus<Block>>;
|
||||||
|
|
||||||
|
fn execute_with_client<PClient, Api, PBackend>(self, client: Arc<PClient>) -> Self::Output
|
||||||
|
where
|
||||||
|
<Api as sp_api::ApiExt<PBlock>>::StateBackend: sp_api::StateBackend<HashFor<PBlock>>,
|
||||||
|
PBackend: Backend<PBlock>,
|
||||||
|
PBackend::State: sp_api::StateBackend<sp_runtime::traits::BlakeTwo256>,
|
||||||
|
Api: polkadot_service::RuntimeApiCollection<StateBackend = PBackend::State>,
|
||||||
|
PClient: polkadot_service::AbstractClient<PBlock, PBackend, Api = Api> + 'static,
|
||||||
|
{
|
||||||
|
Box::new(AuraConsensus::new::<P, _, _, _, _, _, _>(
|
||||||
|
self.para_client,
|
||||||
|
self.block_import,
|
||||||
|
self.sync_oracle,
|
||||||
|
self.proposer_factory,
|
||||||
|
self.force_authoring,
|
||||||
|
self.backoff_authoring_blocks,
|
||||||
|
self.keystore,
|
||||||
|
self.create_inherent_data_providers,
|
||||||
|
client.clone(),
|
||||||
|
self.relay_chain_backend,
|
||||||
|
self.slot_duration,
|
||||||
|
self.telemetry,
|
||||||
|
self.block_proposal_slot_portion,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,6 @@ polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "m
|
|||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-client-consensus-common = { path = "../common" }
|
cumulus-client-consensus-common = { path = "../common" }
|
||||||
cumulus-primitives-core = { path = "../../../primitives/core" }
|
cumulus-primitives-core = { path = "../../../primitives/core" }
|
||||||
cumulus-primitives-parachain-inherent = { path = "../../../primitives/parachain-inherent" }
|
|
||||||
|
|
||||||
# Other deps
|
# Other deps
|
||||||
futures = { version = "0.3.8", features = ["compat"] }
|
futures = { version = "0.3.8", features = ["compat"] }
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ where
|
|||||||
.create_inherent_data_providers
|
.create_inherent_data_providers
|
||||||
.create_inherent_data_providers(*header.parent_hash(), ())
|
.create_inherent_data_providers(*header.parent_hash(), ())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let inherent_data = inherent_data_providers
|
let inherent_data = inherent_data_providers
|
||||||
.create_inherent_data()
|
.create_inherent_data()
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ use cumulus_primitives_core::{
|
|||||||
relay_chain::v1::{Block as PBlock, Hash as PHash, ParachainHost},
|
relay_chain::v1::{Block as PBlock, Hash as PHash, ParachainHost},
|
||||||
ParaId, PersistedValidationData,
|
ParaId, PersistedValidationData,
|
||||||
};
|
};
|
||||||
use cumulus_primitives_parachain_inherent::ParachainInherentData;
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use polkadot_service::ClientHandle;
|
use polkadot_service::ClientHandle;
|
||||||
use sc_client_api::Backend;
|
use sc_client_api::Backend;
|
||||||
@@ -89,7 +88,7 @@ where
|
|||||||
RClient: ProvideRuntimeApi<PBlock>,
|
RClient: ProvideRuntimeApi<PBlock>,
|
||||||
RClient::Api: ParachainHost<PBlock>,
|
RClient::Api: ParachainHost<PBlock>,
|
||||||
RBackend: Backend<PBlock>,
|
RBackend: Backend<PBlock>,
|
||||||
CIDP: CreateInherentDataProviders<B, ()>,
|
CIDP: CreateInherentDataProviders<B, (PHash, PersistedValidationData)>,
|
||||||
{
|
{
|
||||||
/// Create a new instance of relay-chain provided consensus.
|
/// Create a new instance of relay-chain provided consensus.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@@ -120,18 +119,18 @@ where
|
|||||||
) -> Option<InherentData> {
|
) -> Option<InherentData> {
|
||||||
let inherent_data_providers = self
|
let inherent_data_providers = self
|
||||||
.create_inherent_data_providers
|
.create_inherent_data_providers
|
||||||
.create_inherent_data_providers(parent, ())
|
.create_inherent_data_providers(parent, (relay_parent, validation_data.clone()))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
error = ?e,
|
error = ?e,
|
||||||
"Failed to create inherent data providers",
|
"Failed to create inherent data providers.",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let mut inherent_data = inherent_data_providers
|
inherent_data_providers
|
||||||
.create_inherent_data()
|
.create_inherent_data()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
@@ -140,31 +139,7 @@ where
|
|||||||
"Failed to create inherent data.",
|
"Failed to create inherent data.",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()
|
||||||
|
|
||||||
let parachain_inherent_data = ParachainInherentData::create_at(
|
|
||||||
relay_parent,
|
|
||||||
&*self.relay_chain_client,
|
|
||||||
&*self.relay_chain_backend,
|
|
||||||
validation_data,
|
|
||||||
self.para_id,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
inherent_data
|
|
||||||
.put_data(
|
|
||||||
cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER,
|
|
||||||
¶chain_inherent_data,
|
|
||||||
)
|
|
||||||
.map_err(|e| {
|
|
||||||
tracing::error!(
|
|
||||||
target: LOG_TARGET,
|
|
||||||
error = ?e,
|
|
||||||
"Failed to put the system inherent into inherent data.",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
Some(inherent_data)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +159,7 @@ where
|
|||||||
ProofRecording = EnableProofRecording,
|
ProofRecording = EnableProofRecording,
|
||||||
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
Proof = <EnableProofRecording as ProofRecording>::Proof,
|
||||||
>,
|
>,
|
||||||
CIDP: CreateInherentDataProviders<B, ()>,
|
CIDP: CreateInherentDataProviders<B, (PHash, PersistedValidationData)>,
|
||||||
{
|
{
|
||||||
async fn produce_candidate(
|
async fn produce_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -201,7 +176,9 @@ where
|
|||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let inherent_data = self.inherent_data(parent.hash(), &validation_data, relay_parent).await?;
|
let inherent_data = self
|
||||||
|
.inherent_data(parent.hash(), &validation_data, relay_parent)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let Proposal {
|
let Proposal {
|
||||||
block,
|
block,
|
||||||
@@ -288,7 +265,7 @@ where
|
|||||||
RBackend: Backend<PBlock> + 'static,
|
RBackend: Backend<PBlock> + 'static,
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
||||||
sc_client_api::StateBackendFor<RBackend, PBlock>: sc_client_api::StateBackend<HashFor<PBlock>>,
|
sc_client_api::StateBackendFor<RBackend, PBlock>: sc_client_api::StateBackend<HashFor<PBlock>>,
|
||||||
CIDP: CreateInherentDataProviders<Block, ()> + 'static,
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)> + 'static,
|
||||||
{
|
{
|
||||||
RelayChainConsensusBuilder::new(
|
RelayChainConsensusBuilder::new(
|
||||||
para_id,
|
para_id,
|
||||||
@@ -331,7 +308,7 @@ where
|
|||||||
>,
|
>,
|
||||||
BI: BlockImport<Block> + Send + Sync + 'static,
|
BI: BlockImport<Block> + Send + Sync + 'static,
|
||||||
RBackend: Backend<PBlock> + 'static,
|
RBackend: Backend<PBlock> + 'static,
|
||||||
CIDP: CreateInherentDataProviders<Block, ()> + 'static,
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)> + 'static,
|
||||||
{
|
{
|
||||||
/// Create a new instance of the builder.
|
/// Create a new instance of the builder.
|
||||||
fn new(
|
fn new(
|
||||||
@@ -374,7 +351,7 @@ where
|
|||||||
>,
|
>,
|
||||||
BI: BlockImport<Block> + Send + Sync + 'static,
|
BI: BlockImport<Block> + Send + Sync + 'static,
|
||||||
RBackend: Backend<PBlock> + 'static,
|
RBackend: Backend<PBlock> + 'static,
|
||||||
CIDP: CreateInherentDataProviders<Block, ()> + 'static,
|
CIDP: CreateInherentDataProviders<Block, (PHash, PersistedValidationData)> + 'static,
|
||||||
{
|
{
|
||||||
type Output = Box<dyn ParachainConsensus<Block>>;
|
type Output = Box<dyn ParachainConsensus<Block>>;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
[package]
|
||||||
|
name = "cumulus-pallet-aura-ext"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
description = "AURA consensus extension pallet for parachains"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Substrate dependencies
|
||||||
|
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-application-crypto = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
|
# Other Dependencies
|
||||||
|
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"]}
|
||||||
|
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cumulus-pallet-parachain-system = { path = "../parachain-system" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "std" ]
|
||||||
|
std = [
|
||||||
|
"codec/std",
|
||||||
|
"serde",
|
||||||
|
"frame-support/std",
|
||||||
|
"sp-runtime/std",
|
||||||
|
"sp-std/std",
|
||||||
|
"frame-system/std",
|
||||||
|
"frame-executive/std",
|
||||||
|
"pallet-aura/std",
|
||||||
|
"sp-consensus-aura/std",
|
||||||
|
"sp-application-crypto/std",
|
||||||
|
]
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Cumulus.
|
||||||
|
|
||||||
|
// Cumulus is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Cumulus is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Cumulus extension pallet for AuRa
|
||||||
|
//!
|
||||||
|
//! This pallets extends the Substrate AuRa pallet to make it compatible with parachains. It
|
||||||
|
//! provides the [`Pallet`], the [`Config`] and the [`GenesisConfig`].
|
||||||
|
//!
|
||||||
|
//! It is also required that the parachain runtime uses the provided [`BlockExecutor`] to properly
|
||||||
|
//! check the constructed block on the relay chain.
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//!# struct Runtime;
|
||||||
|
//!# struct Executive;
|
||||||
|
//! cumulus_pallet_parachain_system::register_validate_block!(
|
||||||
|
//! Runtime,
|
||||||
|
//! cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||||
|
//! );
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
use frame_support::traits::{ExecuteBlock, FindAuthor};
|
||||||
|
use sp_application_crypto::RuntimeAppPublic;
|
||||||
|
use sp_consensus_aura::digests::CompatibleDigestItem;
|
||||||
|
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
|
||||||
|
|
||||||
|
type Aura<T> = pallet_aura::Pallet<T>;
|
||||||
|
|
||||||
|
pub use pallet::*;
|
||||||
|
|
||||||
|
#[frame_support::pallet]
|
||||||
|
pub mod pallet {
|
||||||
|
use super::*;
|
||||||
|
use frame_support::pallet_prelude::*;
|
||||||
|
use frame_system::pallet_prelude::*;
|
||||||
|
use sp_std::vec::Vec;
|
||||||
|
|
||||||
|
/// The configuration trait.
|
||||||
|
#[pallet::config]
|
||||||
|
pub trait Config: pallet_aura::Config + frame_system::Config {}
|
||||||
|
|
||||||
|
#[pallet::pallet]
|
||||||
|
pub struct Pallet<T>(_);
|
||||||
|
|
||||||
|
#[pallet::hooks]
|
||||||
|
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
||||||
|
fn on_finalize(_: BlockNumberFor<T>) {
|
||||||
|
// Update to the latest AuRa authorities.
|
||||||
|
Authorities::<T>::put(Aura::<T>::authorities());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
|
||||||
|
// Fetch the authorities once to get them into the storage proof of the PoV.
|
||||||
|
Authorities::<T>::get();
|
||||||
|
|
||||||
|
T::DbWeight::get().reads_writes(2, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pallet::call]
|
||||||
|
impl<T: Config> Pallet<T> {}
|
||||||
|
|
||||||
|
/// Serves as cache for the authorities.
|
||||||
|
///
|
||||||
|
/// The authorities in AuRa are overwritten in `on_initialize` when we switch to a new session,
|
||||||
|
/// but we require the old authorities to verify the seal when validating a PoV. This will always
|
||||||
|
/// be updated to the latest AuRa authorities in `on_finalize`.
|
||||||
|
#[pallet::storage]
|
||||||
|
pub(crate) type Authorities<T: Config> = StorageValue<_, Vec<T::AuthorityId>, ValueQuery>;
|
||||||
|
|
||||||
|
#[pallet::genesis_config]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct GenesisConfig;
|
||||||
|
|
||||||
|
#[pallet::genesis_build]
|
||||||
|
impl<T: Config> GenesisBuild<T> for GenesisConfig {
|
||||||
|
fn build(&self) {
|
||||||
|
let authorities = Aura::<T>::authorities();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
!authorities.is_empty(),
|
||||||
|
"AuRa authorities empty, maybe wrong order in `construct_runtime!`?",
|
||||||
|
);
|
||||||
|
|
||||||
|
Authorities::<T>::put(authorities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The block executor used when validating a PoV at the relay chain.
|
||||||
|
///
|
||||||
|
/// When executing the block it will verify the block seal to ensure that the correct author created
|
||||||
|
/// the block.
|
||||||
|
pub struct BlockExecutor<T, I>(sp_std::marker::PhantomData<(T, I)>);
|
||||||
|
|
||||||
|
impl<Block, T, I> ExecuteBlock<Block> for BlockExecutor<T, I>
|
||||||
|
where
|
||||||
|
Block: BlockT,
|
||||||
|
T: Config,
|
||||||
|
I: ExecuteBlock<Block>,
|
||||||
|
{
|
||||||
|
fn execute_block(block: Block) {
|
||||||
|
let (mut header, extrinsics) = block.deconstruct();
|
||||||
|
// We need to fetch the authorities before we execute the block, to get the authorities
|
||||||
|
// before any potential update.
|
||||||
|
let authorities = Authorities::<T>::get();
|
||||||
|
|
||||||
|
let mut seal = None;
|
||||||
|
header.digest_mut().logs.retain(|s| {
|
||||||
|
let s =
|
||||||
|
CompatibleDigestItem::<<T::AuthorityId as RuntimeAppPublic>::Signature>::as_aura_seal(s);
|
||||||
|
match (s, seal.is_some()) {
|
||||||
|
(Some(_), true) => panic!("Found multiple AuRa seal digests"),
|
||||||
|
(None, _) => true,
|
||||||
|
(Some(s), false) => {
|
||||||
|
seal = Some(s);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let seal = seal.expect("Could not find an AuRa seal digest!");
|
||||||
|
|
||||||
|
let author = Aura::<T>::find_author(
|
||||||
|
header
|
||||||
|
.digest()
|
||||||
|
.logs()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|d| d.as_pre_runtime()),
|
||||||
|
)
|
||||||
|
.expect("Could not find AuRa author index!");
|
||||||
|
|
||||||
|
let pre_hash = header.hash();
|
||||||
|
|
||||||
|
if !authorities
|
||||||
|
.get(author as usize)
|
||||||
|
.unwrap_or_else(||
|
||||||
|
panic!("Invalid AuRa author index {} for authorities: {:?}", author, authorities)
|
||||||
|
)
|
||||||
|
.verify(&pre_hash, &seal)
|
||||||
|
{
|
||||||
|
panic!("Invalid AuRa seal");
|
||||||
|
}
|
||||||
|
|
||||||
|
I::execute_block(Block::new(header, extrinsics));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,7 +69,7 @@ fn set_and_run_with_validation_params<R>(mut params: ValidationParams, f: impl F
|
|||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! register_validate_block {
|
macro_rules! register_validate_block {
|
||||||
($runtime:ty, $block_executor:ty) => {
|
($runtime:ty, $block_executor:ty $( , )? ) => {
|
||||||
$crate::register_validate_block_impl!($runtime, $block_executor);
|
$crate::register_validate_block_impl!($runtime, $block_executor);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,21 @@ sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "
|
|||||||
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||||
|
|
||||||
|
# Polkadot dependencies
|
||||||
|
polkadot-service = { git = "https://github.com/paritytech/polkadot", optional = true, branch = "master" }
|
||||||
|
|
||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-primitives-core = { path = "../core", default-features = false }
|
cumulus-primitives-core = { path = "../core", default-features = false }
|
||||||
|
|
||||||
# Other dependencies
|
# Other dependencies
|
||||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
|
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ "derive" ] }
|
||||||
tracing = { version = "0.1.22", optional = true }
|
tracing = { version = "0.1.22", optional = true }
|
||||||
|
async-trait = { version = "0.1.42", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "std" ]
|
default = [ "std" ]
|
||||||
std = [
|
std = [
|
||||||
|
"async-trait",
|
||||||
"codec/std",
|
"codec/std",
|
||||||
"cumulus-primitives-core/std",
|
"cumulus-primitives-core/std",
|
||||||
"sp-inherents/std",
|
"sp-inherents/std",
|
||||||
@@ -36,4 +41,5 @@ std = [
|
|||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
"sc-client-api",
|
"sc-client-api",
|
||||||
"sp-api",
|
"sp-api",
|
||||||
|
"polkadot-service",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use cumulus_primitives_core::{
|
|||||||
},
|
},
|
||||||
InboundDownwardMessage, InboundHrmpMessage, ParaId, PersistedValidationData,
|
InboundDownwardMessage, InboundHrmpMessage, ParaId, PersistedValidationData,
|
||||||
};
|
};
|
||||||
|
use polkadot_service::{Client, ClientHandle, ExecuteWithClient};
|
||||||
use sc_client_api::Backend;
|
use sc_client_api::Backend;
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::ProvideRuntimeApi;
|
||||||
use sp_runtime::generic::BlockId;
|
use sp_runtime::generic::BlockId;
|
||||||
@@ -210,7 +211,8 @@ impl ParachainInherentData {
|
|||||||
PClient: ProvideRuntimeApi<PBlock>,
|
PClient: ProvideRuntimeApi<PBlock>,
|
||||||
PClient::Api: ParachainHost<PBlock>,
|
PClient::Api: ParachainHost<PBlock>,
|
||||||
{
|
{
|
||||||
let relay_chain_state = collect_relay_storage_proof(polkadot_backend, para_id, relay_parent)?;
|
let relay_chain_state =
|
||||||
|
collect_relay_storage_proof(polkadot_backend, para_id, relay_parent)?;
|
||||||
let downward_messages = retrieve_dmq_contents(polkadot_client, para_id, relay_parent)?;
|
let downward_messages = retrieve_dmq_contents(polkadot_client, para_id, relay_parent)?;
|
||||||
let horizontal_messages =
|
let horizontal_messages =
|
||||||
retrieve_all_inbound_hrmp_channel_contents(polkadot_client, para_id, relay_parent)?;
|
retrieve_all_inbound_hrmp_channel_contents(polkadot_client, para_id, relay_parent)?;
|
||||||
@@ -222,4 +224,68 @@ impl ParachainInherentData {
|
|||||||
relay_chain_state,
|
relay_chain_state,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create the [`ParachainInherentData`] at the given `relay_parent`.
|
||||||
|
///
|
||||||
|
/// Returns `None` if the creation failed.
|
||||||
|
pub fn create_at_with_client(
|
||||||
|
relay_parent: PHash,
|
||||||
|
polkadot_client: &Client,
|
||||||
|
relay_chain_backend: &impl Backend<PBlock>,
|
||||||
|
validation_data: &PersistedValidationData,
|
||||||
|
para_id: ParaId,
|
||||||
|
) -> Option<ParachainInherentData> {
|
||||||
|
polkadot_client.execute_with(CreateAtWithClient {
|
||||||
|
relay_chain_backend,
|
||||||
|
validation_data,
|
||||||
|
para_id,
|
||||||
|
relay_parent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl sp_inherents::InherentDataProvider for ParachainInherentData {
|
||||||
|
fn provide_inherent_data(
|
||||||
|
&self,
|
||||||
|
inherent_data: &mut sp_inherents::InherentData,
|
||||||
|
) -> Result<(), sp_inherents::Error> {
|
||||||
|
inherent_data.put_data(crate::INHERENT_IDENTIFIER, &self)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn try_handle_error(
|
||||||
|
&self,
|
||||||
|
_: &sp_inherents::InherentIdentifier,
|
||||||
|
_: &[u8],
|
||||||
|
) -> Option<Result<(), sp_inherents::Error>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Special structure to run [`ParachainInherentData::create_at`] with a [`Client`].
|
||||||
|
struct CreateAtWithClient<'a, B> {
|
||||||
|
relay_parent: PHash,
|
||||||
|
relay_chain_backend: &'a B,
|
||||||
|
validation_data: &'a PersistedValidationData,
|
||||||
|
para_id: ParaId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, B> ExecuteWithClient for CreateAtWithClient<'a, B>
|
||||||
|
where
|
||||||
|
B: Backend<PBlock>,
|
||||||
|
{
|
||||||
|
type Output = Option<ParachainInherentData>;
|
||||||
|
|
||||||
|
fn execute_with_client<Client, Api, Backend>(
|
||||||
|
self,
|
||||||
|
client: std::sync::Arc<Client>,
|
||||||
|
) -> Self::Output where Client: ProvideRuntimeApi<PBlock>, Client::Api: ParachainHost<PBlock> {
|
||||||
|
ParachainInherentData::create_at(
|
||||||
|
self.relay_parent,
|
||||||
|
&*client,
|
||||||
|
self.relay_chain_backend,
|
||||||
|
self.validation_data,
|
||||||
|
self.para_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,24 +46,29 @@ sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch
|
|||||||
sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
# RPC related dependencies
|
# RPC related dependencies
|
||||||
jsonrpc-core = "15.1.0"
|
jsonrpc-core = "15.1.0"
|
||||||
|
|
||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-client-cli = { path = "../client/cli" }
|
cumulus-client-cli = { path = "../client/cli" }
|
||||||
|
cumulus-client-consensus-aura = { path = "../client/consensus/aura" }
|
||||||
cumulus-client-consensus-relay-chain = { path = "../client/consensus/relay-chain" }
|
cumulus-client-consensus-relay-chain = { path = "../client/consensus/relay-chain" }
|
||||||
|
cumulus-client-consensus-common = { path = "../client/consensus/common" }
|
||||||
cumulus-client-collator = { path = "../client/collator" }
|
cumulus-client-collator = { path = "../client/collator" }
|
||||||
cumulus-client-service = { path = "../client/service" }
|
cumulus-client-service = { path = "../client/service" }
|
||||||
cumulus-client-network = { path = "../client/network" }
|
cumulus-client-network = { path = "../client/network" }
|
||||||
cumulus-primitives-core = { path = "../primitives/core" }
|
cumulus-primitives-core = { path = "../primitives/core" }
|
||||||
|
cumulus-primitives-parachain-inherent = { path = "../primitives/parachain-inherent" }
|
||||||
|
|
||||||
# Polkadot dependencies
|
# Polkadot dependencies
|
||||||
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ sp-offchain = { git = "https://github.com/paritytech/substrate", default-feature
|
|||||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
sp-inherents = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
frame-executive = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
@@ -33,8 +34,10 @@ pallet-randomness-collective-flip = { git = "https://github.com/paritytech/subst
|
|||||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
|
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
|
||||||
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
||||||
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||||
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
||||||
@@ -85,6 +88,7 @@ std = [
|
|||||||
"pallet-transaction-payment/std",
|
"pallet-transaction-payment/std",
|
||||||
"parachain-info/std",
|
"parachain-info/std",
|
||||||
"rococo-parachain-primitives/std",
|
"rococo-parachain-primitives/std",
|
||||||
|
"cumulus-pallet-aura-ext/std",
|
||||||
"cumulus-pallet-dmp-queue/std",
|
"cumulus-pallet-dmp-queue/std",
|
||||||
"cumulus-pallet-parachain-system/std",
|
"cumulus-pallet-parachain-system/std",
|
||||||
"cumulus-pallet-xcmp-queue/std",
|
"cumulus-pallet-xcmp-queue/std",
|
||||||
@@ -95,4 +99,6 @@ std = [
|
|||||||
"xcm/std",
|
"xcm/std",
|
||||||
"xcm-builder/std",
|
"xcm-builder/std",
|
||||||
"xcm-executor/std",
|
"xcm-executor/std",
|
||||||
|
"pallet-aura/std",
|
||||||
|
"sp-consensus-aura/std",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ pub use pallet_timestamp::Call as TimestampCall;
|
|||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
pub use sp_runtime::BuildStorage;
|
pub use sp_runtime::BuildStorage;
|
||||||
pub use sp_runtime::{Perbill, Permill};
|
pub use sp_runtime::{Perbill, Permill};
|
||||||
|
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
|
||||||
|
|
||||||
// XCM imports
|
// XCM imports
|
||||||
use polkadot_parachain::primitives::Sibling;
|
use polkadot_parachain::primitives::Sibling;
|
||||||
@@ -71,7 +72,9 @@ use frame_support::traits::Contains;
|
|||||||
pub type SessionHandlers = ();
|
pub type SessionHandlers = ();
|
||||||
|
|
||||||
impl_opaque_keys! {
|
impl_opaque_keys! {
|
||||||
pub struct SessionKeys {}
|
pub struct SessionKeys {
|
||||||
|
pub aura: Aura,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This runtime version.
|
/// This runtime version.
|
||||||
@@ -85,7 +88,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
transaction_version: 1,
|
transaction_version: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MILLISECS_PER_BLOCK: u64 = 6000;
|
pub const MILLISECS_PER_BLOCK: u64 = 12000;
|
||||||
|
|
||||||
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
||||||
|
|
||||||
@@ -248,6 +251,8 @@ impl cumulus_pallet_parachain_system::Config for Runtime {
|
|||||||
|
|
||||||
impl parachain_info::Config for Runtime {}
|
impl parachain_info::Config for Runtime {}
|
||||||
|
|
||||||
|
impl cumulus_pallet_aura_ext::Config for Runtime {}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const RocLocation: MultiLocation = X1(Parent);
|
pub const RocLocation: MultiLocation = X1(Parent);
|
||||||
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
|
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
|
||||||
@@ -419,14 +424,8 @@ impl pallet_assets::Config for Runtime {
|
|||||||
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
|
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
impl pallet_aura::Config for Runtime {
|
||||||
fn encode_call() {
|
type AuthorityId = AuraId;
|
||||||
let hash = hex_literal::hex!["0af9fef6f950ca3ac8ac4766200454b1039ffb7b2d0827fffd5e47bd43761437"].into();
|
|
||||||
let call = Call::ParachainSystem(cumulus_pallet_parachain_system::Call::authorize_upgrade(hash));
|
|
||||||
assert_eq!(
|
|
||||||
hex::encode(codec::Encode::encode(&call)),
|
|
||||||
"14030af9fef6f950ca3ac8ac4766200454b1039ffb7b2d0827fffd5e47bd43761437",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
construct_runtime! {
|
construct_runtime! {
|
||||||
@@ -447,6 +446,9 @@ construct_runtime! {
|
|||||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
|
||||||
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 31,
|
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 31,
|
||||||
|
|
||||||
|
Aura: pallet_aura::{Pallet, Config<T>},
|
||||||
|
AuraExt: cumulus_pallet_aura_ext::{Pallet, Config},
|
||||||
|
|
||||||
// XCM helpers.
|
// XCM helpers.
|
||||||
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
|
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
|
||||||
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
|
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
|
||||||
@@ -496,7 +498,7 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn execute_block(block: Block) {
|
fn execute_block(block: Block) {
|
||||||
Executive::execute_block(block)
|
Executive::execute_block(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||||
@@ -556,6 +558,19 @@ impl_runtime_apis! {
|
|||||||
SessionKeys::generate(seed)
|
SessionKeys::generate(seed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||||
|
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||||
|
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn authorities() -> Vec<AuraId> {
|
||||||
|
Aura::authorities()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cumulus_pallet_parachain_system::register_validate_block!(Runtime, Executive);
|
cumulus_pallet_parachain_system::register_validate_block!(
|
||||||
|
Runtime,
|
||||||
|
cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||||
|
);
|
||||||
|
|||||||
@@ -209,8 +209,8 @@ impl Config for XcmConfig {
|
|||||||
type IsTeleporter = (); // balances not supported
|
type IsTeleporter = (); // balances not supported
|
||||||
type LocationInverter = LocationInverter<Ancestry>;
|
type LocationInverter = LocationInverter<Ancestry>;
|
||||||
type Barrier = AllowUnpaidExecutionFrom<JustTheParent>;
|
type Barrier = AllowUnpaidExecutionFrom<JustTheParent>;
|
||||||
type Weigher = FixedWeightBounds<UnitWeightCost, Call>; // balances not supported
|
type Weigher = FixedWeightBounds<UnitWeightCost, Call>; // balances not supported
|
||||||
type Trader = (); // balances not supported
|
type Trader = (); // balances not supported
|
||||||
type ResponseHandler = (); // Don't handle responses for now.
|
type ResponseHandler = (); // Don't handle responses for now.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,16 +219,6 @@ impl cumulus_pallet_xcm::Config for Runtime {
|
|||||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn encode_call() {
|
|
||||||
let hash = hex_literal::hex!["0af9fef6f950ca3ac8ac4766200454b1039ffb7b2d0827fffd5e47bd43761437"].into();
|
|
||||||
let call = Call::ParachainSystem(cumulus_pallet_parachain_system::Call::authorize_upgrade(hash));
|
|
||||||
assert_eq!(
|
|
||||||
hex::encode(codec::Encode::encode(&call)),
|
|
||||||
"01030af9fef6f950ca3ac8ac4766200454b1039ffb7b2d0827fffd5e47bd43761437",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
construct_runtime! {
|
construct_runtime! {
|
||||||
pub enum Runtime where
|
pub enum Runtime where
|
||||||
Block = Block,
|
Block = Block,
|
||||||
|
|||||||
@@ -16,11 +16,12 @@
|
|||||||
|
|
||||||
use cumulus_primitives_core::ParaId;
|
use cumulus_primitives_core::ParaId;
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
|
use parachain_runtime::AuraId;
|
||||||
use rococo_parachain_primitives::{AccountId, Signature};
|
use rococo_parachain_primitives::{AccountId, Signature};
|
||||||
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
|
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
|
||||||
use sc_service::ChainType;
|
use sc_service::ChainType;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sp_core::{sr25519, Pair, Public};
|
use sp_core::{sr25519, Pair, Public, crypto::UncheckedInto};
|
||||||
use sp_runtime::traits::{IdentifyAccount, Verify};
|
use sp_runtime::traits::{IdentifyAccount, Verify};
|
||||||
|
|
||||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||||
@@ -71,6 +72,10 @@ pub fn get_chain_spec(id: ParaId) -> ChainSpec {
|
|||||||
move || {
|
move || {
|
||||||
testnet_genesis(
|
testnet_genesis(
|
||||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
vec![
|
||||||
|
get_from_seed::<AuraId>("Alice"),
|
||||||
|
get_from_seed::<AuraId>("Bob"),
|
||||||
|
],
|
||||||
vec![
|
vec![
|
||||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||||
@@ -124,6 +129,12 @@ pub fn staging_test_net(id: ParaId) -> ChainSpec {
|
|||||||
move || {
|
move || {
|
||||||
testnet_genesis(
|
testnet_genesis(
|
||||||
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
||||||
|
vec![
|
||||||
|
// $secret//one
|
||||||
|
hex!["aad9fa2249f87a210a0f93400b7f90e47b810c6d65caa0ca3f5af982904c2a33"].unchecked_into(),
|
||||||
|
// $secret//two
|
||||||
|
hex!["d47753f0cca9dd8da00c70e82ec4fc5501a69c49a5952a643d18802837c88212"].unchecked_into(),
|
||||||
|
],
|
||||||
vec![
|
vec![
|
||||||
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
||||||
],
|
],
|
||||||
@@ -143,6 +154,7 @@ pub fn staging_test_net(id: ParaId) -> ChainSpec {
|
|||||||
|
|
||||||
fn testnet_genesis(
|
fn testnet_genesis(
|
||||||
root_key: AccountId,
|
root_key: AccountId,
|
||||||
|
initial_authorities: Vec<AuraId>,
|
||||||
endowed_accounts: Vec<AccountId>,
|
endowed_accounts: Vec<AccountId>,
|
||||||
id: ParaId,
|
id: ParaId,
|
||||||
) -> parachain_runtime::GenesisConfig {
|
) -> parachain_runtime::GenesisConfig {
|
||||||
@@ -162,6 +174,10 @@ fn testnet_genesis(
|
|||||||
},
|
},
|
||||||
pallet_sudo: parachain_runtime::SudoConfig { key: root_key },
|
pallet_sudo: parachain_runtime::SudoConfig { key: root_key },
|
||||||
parachain_info: parachain_runtime::ParachainInfoConfig { parachain_id: id },
|
parachain_info: parachain_runtime::ParachainInfoConfig { parachain_id: id },
|
||||||
|
pallet_aura: parachain_runtime::AuraConfig {
|
||||||
|
authorities: initial_authorities,
|
||||||
|
},
|
||||||
|
cumulus_pallet_aura_ext: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ use crate::{
|
|||||||
cli::{Cli, RelayChainCli, Subcommand},
|
cli::{Cli, RelayChainCli, Subcommand},
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use cumulus_primitives_core::ParaId;
|
|
||||||
use cumulus_client_service::genesis::generate_genesis_block;
|
use cumulus_client_service::genesis::generate_genesis_block;
|
||||||
|
use cumulus_primitives_core::ParaId;
|
||||||
use log::info;
|
use log::info;
|
||||||
use parachain_runtime::Block;
|
use parachain_runtime::Block;
|
||||||
use polkadot_parachain::primitives::AccountIdConversion;
|
use polkadot_parachain::primitives::AccountIdConversion;
|
||||||
@@ -28,9 +28,7 @@ use sc_cli::{
|
|||||||
ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,
|
ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,
|
||||||
NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli,
|
NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli,
|
||||||
};
|
};
|
||||||
use sc_service::{
|
use sc_service::config::{BasePath, PrometheusConfig};
|
||||||
config::{BasePath, PrometheusConfig},
|
|
||||||
};
|
|
||||||
use sp_core::hexdisplay::HexDisplay;
|
use sp_core::hexdisplay::HexDisplay;
|
||||||
use sp_runtime::traits::Block as BlockT;
|
use sp_runtime::traits::Block as BlockT;
|
||||||
use std::{io::Write, net::SocketAddr};
|
use std::{io::Write, net::SocketAddr};
|
||||||
@@ -157,13 +155,19 @@ macro_rules! construct_async_run {
|
|||||||
let runner = $cli.create_runner($cmd)?;
|
let runner = $cli.create_runner($cmd)?;
|
||||||
if use_shell_runtime(&runner.config().chain_spec) {
|
if use_shell_runtime(&runner.config().chain_spec) {
|
||||||
runner.async_run(|$config| {
|
runner.async_run(|$config| {
|
||||||
let $components = new_partial::<shell_runtime::RuntimeApi, ShellRuntimeExecutor>(&$config)?;
|
let $components = new_partial::<shell_runtime::RuntimeApi, ShellRuntimeExecutor, _>(
|
||||||
|
&$config,
|
||||||
|
crate::service::shell_build_import_queue,
|
||||||
|
)?;
|
||||||
let task_manager = $components.task_manager;
|
let task_manager = $components.task_manager;
|
||||||
{ $( $code )* }.map(|v| (v, task_manager))
|
{ $( $code )* }.map(|v| (v, task_manager))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
runner.async_run(|$config| {
|
runner.async_run(|$config| {
|
||||||
let $components = new_partial::<parachain_runtime::RuntimeApi, RuntimeExecutor>(&$config)?;
|
let $components = new_partial::<parachain_runtime::RuntimeApi, RuntimeExecutor, _>(
|
||||||
|
&$config,
|
||||||
|
crate::service::build_import_queue,
|
||||||
|
)?;
|
||||||
let task_manager = $components.task_manager;
|
let task_manager = $components.task_manager;
|
||||||
{ $( $code )* }.map(|v| (v, task_manager))
|
{ $( $code )* }.map(|v| (v, task_manager))
|
||||||
})
|
})
|
||||||
@@ -180,18 +184,26 @@ pub fn run() -> Result<()> {
|
|||||||
let runner = cli.create_runner(cmd)?;
|
let runner = cli.create_runner(cmd)?;
|
||||||
runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
|
runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
|
||||||
}
|
}
|
||||||
Some(Subcommand::CheckBlock(cmd)) => construct_async_run! (|components, cli, cmd, config| {
|
Some(Subcommand::CheckBlock(cmd)) => {
|
||||||
Ok(cmd.run(components.client, components.import_queue))
|
construct_async_run!(|components, cli, cmd, config| {
|
||||||
}),
|
Ok(cmd.run(components.client, components.import_queue))
|
||||||
Some(Subcommand::ExportBlocks(cmd)) => construct_async_run! (|components, cli, cmd, config| {
|
})
|
||||||
Ok(cmd.run(components.client, config.database))
|
}
|
||||||
}),
|
Some(Subcommand::ExportBlocks(cmd)) => {
|
||||||
Some(Subcommand::ExportState(cmd)) => construct_async_run! (|components, cli, cmd, config| {
|
construct_async_run!(|components, cli, cmd, config| {
|
||||||
Ok(cmd.run(components.client, config.chain_spec))
|
Ok(cmd.run(components.client, config.database))
|
||||||
}),
|
})
|
||||||
Some(Subcommand::ImportBlocks(cmd)) => construct_async_run! (|components, cli, cmd, config| {
|
}
|
||||||
Ok(cmd.run(components.client, components.import_queue))
|
Some(Subcommand::ExportState(cmd)) => {
|
||||||
}),
|
construct_async_run!(|components, cli, cmd, config| {
|
||||||
|
Ok(cmd.run(components.client, config.chain_spec))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(Subcommand::ImportBlocks(cmd)) => {
|
||||||
|
construct_async_run!(|components, cli, cmd, config| {
|
||||||
|
Ok(cmd.run(components.client, components.import_queue))
|
||||||
|
})
|
||||||
|
}
|
||||||
Some(Subcommand::PurgeChain(cmd)) => {
|
Some(Subcommand::PurgeChain(cmd)) => {
|
||||||
let runner = cli.create_runner(cmd)?;
|
let runner = cli.create_runner(cmd)?;
|
||||||
|
|
||||||
@@ -213,7 +225,7 @@ pub fn run() -> Result<()> {
|
|||||||
cmd.run(config, polkadot_config)
|
cmd.run(config, polkadot_config)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Some(Subcommand::Revert(cmd)) => construct_async_run! (|components, cli, cmd, config| {
|
Some(Subcommand::Revert(cmd)) => construct_async_run!(|components, cli, cmd, config| {
|
||||||
Ok(cmd.run(components.client, components.backend))
|
Ok(cmd.run(components.client, components.backend))
|
||||||
}),
|
}),
|
||||||
Some(Subcommand::ExportGenesisState(params)) => {
|
Some(Subcommand::ExportGenesisState(params)) => {
|
||||||
|
|||||||
@@ -14,24 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use cumulus_client_consensus_relay_chain::{
|
use cumulus_client_consensus_aura::{
|
||||||
build_relay_chain_consensus, BuildRelayChainConsensusParams,
|
build_aura_consensus, BuildAuraConsensusParams, SlotProportion,
|
||||||
};
|
};
|
||||||
|
use cumulus_client_consensus_common::ParachainConsensus;
|
||||||
use cumulus_client_network::build_block_announce_validator;
|
use cumulus_client_network::build_block_announce_validator;
|
||||||
use cumulus_client_service::{
|
use cumulus_client_service::{
|
||||||
prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,
|
prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,
|
||||||
};
|
};
|
||||||
use cumulus_primitives_core::ParaId;
|
use cumulus_primitives_core::ParaId;
|
||||||
use polkadot_primitives::v0::CollatorPair;
|
use polkadot_primitives::v0::CollatorPair;
|
||||||
use rococo_parachain_primitives::Block;
|
use rococo_parachain_primitives::{Block, Hash};
|
||||||
|
|
||||||
|
use sc_client_api::ExecutorProvider;
|
||||||
use sc_executor::native_executor_instance;
|
use sc_executor::native_executor_instance;
|
||||||
pub use sc_executor::NativeExecutor;
|
use sc_network::NetworkService;
|
||||||
use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager};
|
use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager};
|
||||||
use sc_telemetry::{Telemetry, TelemetryWorker, TelemetryWorkerHandle};
|
use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
|
||||||
use sp_api::ConstructRuntimeApi;
|
use sp_api::ConstructRuntimeApi;
|
||||||
|
use sp_consensus::SlotData;
|
||||||
|
use sp_keystore::SyncCryptoStorePtr;
|
||||||
use sp_runtime::traits::BlakeTwo256;
|
use sp_runtime::traits::BlakeTwo256;
|
||||||
use sp_trie::PrefixedMemoryDB;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use substrate_prometheus_endpoint::Registry;
|
||||||
|
|
||||||
|
pub use sc_executor::NativeExecutor;
|
||||||
|
|
||||||
// Native executor instance.
|
// Native executor instance.
|
||||||
native_executor_instance!(
|
native_executor_instance!(
|
||||||
@@ -51,14 +58,15 @@ native_executor_instance!(
|
|||||||
///
|
///
|
||||||
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
||||||
/// be able to perform chain operations.
|
/// be able to perform chain operations.
|
||||||
pub fn new_partial<RuntimeApi, Executor>(
|
pub fn new_partial<RuntimeApi, Executor, BIQ>(
|
||||||
config: &Configuration,
|
config: &Configuration,
|
||||||
|
build_import_queue: BIQ,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
PartialComponents<
|
PartialComponents<
|
||||||
TFullClient<Block, RuntimeApi, Executor>,
|
TFullClient<Block, RuntimeApi, Executor>,
|
||||||
TFullBackend<Block>,
|
TFullBackend<Block>,
|
||||||
(),
|
(),
|
||||||
sp_consensus::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
|
sp_consensus::DefaultImportQueue<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
sc_transaction_pool::FullPool<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
sc_transaction_pool::FullPool<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
(Option<Telemetry>, Option<TelemetryWorkerHandle>),
|
(Option<Telemetry>, Option<TelemetryWorkerHandle>),
|
||||||
>,
|
>,
|
||||||
@@ -79,6 +87,15 @@ where
|
|||||||
+ sp_block_builder::BlockBuilder<Block>,
|
+ sp_block_builder::BlockBuilder<Block>,
|
||||||
sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
|
sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
|
||||||
Executor: sc_executor::NativeExecutionDispatch + 'static,
|
Executor: sc_executor::NativeExecutionDispatch + 'static,
|
||||||
|
BIQ: FnOnce(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
&Configuration,
|
||||||
|
Option<TelemetryHandle>,
|
||||||
|
&TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sp_consensus::DefaultImportQueue<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
sc_service::Error,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
let telemetry = config
|
let telemetry = config
|
||||||
.telemetry_endpoints
|
.telemetry_endpoints
|
||||||
@@ -105,8 +122,6 @@ where
|
|||||||
telemetry
|
telemetry
|
||||||
});
|
});
|
||||||
|
|
||||||
let registry = config.prometheus_registry();
|
|
||||||
|
|
||||||
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
||||||
config.transaction_pool.clone(),
|
config.transaction_pool.clone(),
|
||||||
config.role.is_authority().into(),
|
config.role.is_authority().into(),
|
||||||
@@ -115,12 +130,11 @@ where
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let import_queue = cumulus_client_consensus_relay_chain::import_queue(
|
let import_queue = build_import_queue(
|
||||||
client.clone(),
|
client.clone(),
|
||||||
client.clone(),
|
config,
|
||||||
|_, _| async { Ok(sp_timestamp::InherentDataProvider::from_system_time()) },
|
telemetry.as_ref().map(|telemetry| telemetry.handle()),
|
||||||
&task_manager.spawn_essential_handle(),
|
&task_manager,
|
||||||
registry.clone(),
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let params = PartialComponents {
|
let params = PartialComponents {
|
||||||
@@ -141,12 +155,14 @@ where
|
|||||||
///
|
///
|
||||||
/// This is the actual implementation that is abstract over the executor and the runtime api.
|
/// This is the actual implementation that is abstract over the executor and the runtime api.
|
||||||
#[sc_tracing::logging::prefix_logs_with("Parachain")]
|
#[sc_tracing::logging::prefix_logs_with("Parachain")]
|
||||||
async fn start_node_impl<RuntimeApi, Executor, RB>(
|
async fn start_node_impl<RuntimeApi, Executor, RB, BIQ, BIC>(
|
||||||
parachain_config: Configuration,
|
parachain_config: Configuration,
|
||||||
collator_key: CollatorPair,
|
collator_key: CollatorPair,
|
||||||
polkadot_config: Configuration,
|
polkadot_config: Configuration,
|
||||||
id: ParaId,
|
id: ParaId,
|
||||||
rpc_ext_builder: RB,
|
rpc_ext_builder: RB,
|
||||||
|
build_import_queue: BIQ,
|
||||||
|
build_consensus: BIC,
|
||||||
) -> sc_service::error::Result<(TaskManager, Arc<TFullClient<Block, RuntimeApi, Executor>>)>
|
) -> sc_service::error::Result<(TaskManager, Arc<TFullClient<Block, RuntimeApi, Executor>>)>
|
||||||
where
|
where
|
||||||
RuntimeApi: ConstructRuntimeApi<Block, TFullClient<Block, RuntimeApi, Executor>>
|
RuntimeApi: ConstructRuntimeApi<Block, TFullClient<Block, RuntimeApi, Executor>>
|
||||||
@@ -168,6 +184,26 @@ where
|
|||||||
) -> jsonrpc_core::IoHandler<sc_rpc::Metadata>
|
) -> jsonrpc_core::IoHandler<sc_rpc::Metadata>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
|
BIQ: FnOnce(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
&Configuration,
|
||||||
|
Option<TelemetryHandle>,
|
||||||
|
&TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sp_consensus::DefaultImportQueue<Block, TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
sc_service::Error,
|
||||||
|
>,
|
||||||
|
BIC: FnOnce(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
Option<&Registry>,
|
||||||
|
Option<TelemetryHandle>,
|
||||||
|
&TaskManager,
|
||||||
|
&polkadot_service::NewFull<polkadot_service::Client>,
|
||||||
|
Arc<sc_transaction_pool::FullPool<Block, TFullClient<Block, RuntimeApi, Executor>>>,
|
||||||
|
Arc<NetworkService<Block, Hash>>,
|
||||||
|
SyncCryptoStorePtr,
|
||||||
|
bool,
|
||||||
|
) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,
|
||||||
{
|
{
|
||||||
if matches!(parachain_config.role, Role::Light) {
|
if matches!(parachain_config.role, Role::Light) {
|
||||||
return Err("Light client not supported!".into());
|
return Err("Light client not supported!".into());
|
||||||
@@ -175,10 +211,10 @@ where
|
|||||||
|
|
||||||
let parachain_config = prepare_node_config(parachain_config);
|
let parachain_config = prepare_node_config(parachain_config);
|
||||||
|
|
||||||
let params = new_partial::<RuntimeApi, Executor>(¶chain_config)?;
|
let params = new_partial::<RuntimeApi, Executor, BIQ>(¶chain_config, build_import_queue)?;
|
||||||
let (mut telemetry, telemetry_worker_handle) = params.other;
|
let (mut telemetry, telemetry_worker_handle) = params.other;
|
||||||
|
|
||||||
let polkadot_full_node = cumulus_client_service::build_polkadot_full_node(
|
let relay_chain_full_node = cumulus_client_service::build_polkadot_full_node(
|
||||||
polkadot_config,
|
polkadot_config,
|
||||||
collator_key.clone(),
|
collator_key.clone(),
|
||||||
telemetry_worker_handle,
|
telemetry_worker_handle,
|
||||||
@@ -191,12 +227,13 @@ where
|
|||||||
let client = params.client.clone();
|
let client = params.client.clone();
|
||||||
let backend = params.backend.clone();
|
let backend = params.backend.clone();
|
||||||
let block_announce_validator = build_block_announce_validator(
|
let block_announce_validator = build_block_announce_validator(
|
||||||
polkadot_full_node.client.clone(),
|
relay_chain_full_node.client.clone(),
|
||||||
id,
|
id,
|
||||||
Box::new(polkadot_full_node.network.clone()),
|
Box::new(relay_chain_full_node.network.clone()),
|
||||||
polkadot_full_node.backend.clone(),
|
relay_chain_full_node.backend.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let force_authoring = parachain_config.force_authoring;
|
||||||
let validator = parachain_config.role.is_authority();
|
let validator = parachain_config.role.is_authority();
|
||||||
let prometheus_registry = parachain_config.prometheus_registry().cloned();
|
let prometheus_registry = parachain_config.prometheus_registry().cloned();
|
||||||
let transaction_pool = params.transaction_pool.clone();
|
let transaction_pool = params.transaction_pool.clone();
|
||||||
@@ -238,25 +275,19 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
if validator {
|
if validator {
|
||||||
let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
|
let parachain_consensus = build_consensus(
|
||||||
task_manager.spawn_handle(),
|
|
||||||
client.clone(),
|
client.clone(),
|
||||||
transaction_pool,
|
|
||||||
prometheus_registry.as_ref(),
|
prometheus_registry.as_ref(),
|
||||||
telemetry.as_ref().map(|x| x.handle()),
|
telemetry.as_ref().map(|t| t.handle()),
|
||||||
);
|
&task_manager,
|
||||||
let spawner = task_manager.spawn_handle();
|
&relay_chain_full_node,
|
||||||
|
transaction_pool,
|
||||||
|
network,
|
||||||
|
params.keystore_container.sync_keystore(),
|
||||||
|
force_authoring,
|
||||||
|
)?;
|
||||||
|
|
||||||
let parachain_consensus = build_relay_chain_consensus(BuildRelayChainConsensusParams {
|
let spawner = task_manager.spawn_handle();
|
||||||
para_id: id,
|
|
||||||
proposer_factory,
|
|
||||||
create_inherent_data_providers: |_, _| async {
|
|
||||||
Ok(sp_timestamp::InherentDataProvider::from_system_time())
|
|
||||||
},
|
|
||||||
block_import: client.clone(),
|
|
||||||
relay_chain_client: polkadot_full_node.client.clone(),
|
|
||||||
relay_chain_backend: polkadot_full_node.backend.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let params = StartCollatorParams {
|
let params = StartCollatorParams {
|
||||||
para_id: id,
|
para_id: id,
|
||||||
@@ -265,7 +296,7 @@ where
|
|||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
task_manager: &mut task_manager,
|
task_manager: &mut task_manager,
|
||||||
collator_key,
|
collator_key,
|
||||||
relay_chain_full_node: polkadot_full_node,
|
relay_chain_full_node,
|
||||||
spawner,
|
spawner,
|
||||||
backend,
|
backend,
|
||||||
parachain_consensus,
|
parachain_consensus,
|
||||||
@@ -278,7 +309,7 @@ where
|
|||||||
announce_block,
|
announce_block,
|
||||||
task_manager: &mut task_manager,
|
task_manager: &mut task_manager,
|
||||||
para_id: id,
|
para_id: id,
|
||||||
polkadot_full_node,
|
polkadot_full_node: relay_chain_full_node,
|
||||||
};
|
};
|
||||||
|
|
||||||
start_full_node(params)?;
|
start_full_node(params)?;
|
||||||
@@ -289,6 +320,58 @@ where
|
|||||||
Ok((task_manager, client))
|
Ok((task_manager, client))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the import queue for the "default" runtime.
|
||||||
|
pub fn build_import_queue(
|
||||||
|
client: Arc<TFullClient<Block, parachain_runtime::RuntimeApi, RuntimeExecutor>>,
|
||||||
|
config: &Configuration,
|
||||||
|
telemetry: Option<TelemetryHandle>,
|
||||||
|
task_manager: &TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sp_consensus::DefaultImportQueue<
|
||||||
|
Block,
|
||||||
|
TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>,
|
||||||
|
>,
|
||||||
|
sc_service::Error,
|
||||||
|
> {
|
||||||
|
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
|
||||||
|
|
||||||
|
let block_import = cumulus_client_consensus_aura::AuraBlockImport::<
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
sp_consensus_aura::sr25519::AuthorityPair,
|
||||||
|
>::new(client.clone(), client.clone());
|
||||||
|
|
||||||
|
cumulus_client_consensus_aura::import_queue::<
|
||||||
|
sp_consensus_aura::sr25519::AuthorityPair,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
>(cumulus_client_consensus_aura::ImportQueueParams {
|
||||||
|
block_import,
|
||||||
|
client: client.clone(),
|
||||||
|
create_inherent_data_providers: move |_, _| async move {
|
||||||
|
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*time,
|
||||||
|
slot_duration.slot_duration(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((time, slot))
|
||||||
|
},
|
||||||
|
registry: config.prometheus_registry().clone(),
|
||||||
|
can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
||||||
|
spawner: &task_manager.spawn_essential_handle(),
|
||||||
|
telemetry,
|
||||||
|
})
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
/// Start a rococo-test parachain node.
|
/// Start a rococo-test parachain node.
|
||||||
pub async fn start_node(
|
pub async fn start_node(
|
||||||
parachain_config: Configuration,
|
parachain_config: Configuration,
|
||||||
@@ -298,16 +381,114 @@ pub async fn start_node(
|
|||||||
) -> sc_service::error::Result<
|
) -> sc_service::error::Result<
|
||||||
(TaskManager, Arc<TFullClient<Block, parachain_runtime::RuntimeApi, RuntimeExecutor>>)
|
(TaskManager, Arc<TFullClient<Block, parachain_runtime::RuntimeApi, RuntimeExecutor>>)
|
||||||
> {
|
> {
|
||||||
start_node_impl::<parachain_runtime::RuntimeApi, RuntimeExecutor, _>(
|
start_node_impl::<parachain_runtime::RuntimeApi, RuntimeExecutor, _, _, _>(
|
||||||
parachain_config,
|
parachain_config,
|
||||||
collator_key,
|
collator_key,
|
||||||
polkadot_config,
|
polkadot_config,
|
||||||
id,
|
id,
|
||||||
|_| Default::default(),
|
|_| Default::default(),
|
||||||
|
build_import_queue,
|
||||||
|
|client,
|
||||||
|
prometheus_registry,
|
||||||
|
telemetry,
|
||||||
|
task_manager,
|
||||||
|
relay_chain_node,
|
||||||
|
transaction_pool,
|
||||||
|
sync_oracle,
|
||||||
|
keystore,
|
||||||
|
force_authoring| {
|
||||||
|
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
|
||||||
|
|
||||||
|
let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
|
||||||
|
task_manager.spawn_handle(),
|
||||||
|
client.clone(),
|
||||||
|
transaction_pool,
|
||||||
|
prometheus_registry.clone(),
|
||||||
|
telemetry.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let relay_chain_backend = relay_chain_node.backend.clone();
|
||||||
|
let relay_chain_client = relay_chain_node.client.clone();
|
||||||
|
Ok(build_aura_consensus::<
|
||||||
|
sp_consensus_aura::sr25519::AuthorityPair,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
>(BuildAuraConsensusParams {
|
||||||
|
proposer_factory,
|
||||||
|
create_inherent_data_providers: move |_, (relay_parent, validation_data)| {
|
||||||
|
let parachain_inherent =
|
||||||
|
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client(
|
||||||
|
relay_parent,
|
||||||
|
&relay_chain_client,
|
||||||
|
&*relay_chain_backend,
|
||||||
|
&validation_data,
|
||||||
|
id,
|
||||||
|
);
|
||||||
|
async move {
|
||||||
|
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*time,
|
||||||
|
slot_duration.slot_duration(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let parachain_inherent = parachain_inherent.ok_or_else(|| {
|
||||||
|
Box::<dyn std::error::Error + Send + Sync>::from(
|
||||||
|
"Failed to create parachain inherent",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok((time, slot, parachain_inherent))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
block_import: client.clone(),
|
||||||
|
relay_chain_client: relay_chain_node.client.clone(),
|
||||||
|
relay_chain_backend: relay_chain_node.backend.clone(),
|
||||||
|
para_client: client.clone(),
|
||||||
|
backoff_authoring_blocks: Option::<()>::None,
|
||||||
|
sync_oracle,
|
||||||
|
keystore,
|
||||||
|
force_authoring,
|
||||||
|
slot_duration,
|
||||||
|
// We got around 500ms for proposing
|
||||||
|
block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),
|
||||||
|
telemetry,
|
||||||
|
}))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the import queue for the shell runtime.
|
||||||
|
pub fn shell_build_import_queue(
|
||||||
|
client: Arc<TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>>,
|
||||||
|
config: &Configuration,
|
||||||
|
_: Option<TelemetryHandle>,
|
||||||
|
task_manager: &TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sp_consensus::DefaultImportQueue<
|
||||||
|
Block,
|
||||||
|
TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>,
|
||||||
|
>,
|
||||||
|
sc_service::Error,
|
||||||
|
> {
|
||||||
|
cumulus_client_consensus_relay_chain::import_queue(
|
||||||
|
client.clone(),
|
||||||
|
client,
|
||||||
|
|_, _| async { Ok(()) },
|
||||||
|
&task_manager.spawn_essential_handle(),
|
||||||
|
config.prometheus_registry().clone(),
|
||||||
|
)
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
/// Start a rococo-shell parachain node.
|
/// Start a rococo-shell parachain node.
|
||||||
pub async fn start_shell_node(
|
pub async fn start_shell_node(
|
||||||
parachain_config: Configuration,
|
parachain_config: Configuration,
|
||||||
@@ -317,12 +498,65 @@ pub async fn start_shell_node(
|
|||||||
) -> sc_service::error::Result<
|
) -> sc_service::error::Result<
|
||||||
(TaskManager, Arc<TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>>)
|
(TaskManager, Arc<TFullClient<Block, shell_runtime::RuntimeApi, ShellRuntimeExecutor>>)
|
||||||
> {
|
> {
|
||||||
start_node_impl::<shell_runtime::RuntimeApi, ShellRuntimeExecutor, _>(
|
start_node_impl::<shell_runtime::RuntimeApi, ShellRuntimeExecutor, _, _, _>(
|
||||||
parachain_config,
|
parachain_config,
|
||||||
collator_key,
|
collator_key,
|
||||||
polkadot_config,
|
polkadot_config,
|
||||||
id,
|
id,
|
||||||
|_| Default::default(),
|
|_| Default::default(),
|
||||||
|
shell_build_import_queue,
|
||||||
|
|client,
|
||||||
|
prometheus_registry,
|
||||||
|
telemetry,
|
||||||
|
task_manager,
|
||||||
|
relay_chain_node,
|
||||||
|
transaction_pool,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_| {
|
||||||
|
let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
|
||||||
|
task_manager.spawn_handle(),
|
||||||
|
client.clone(),
|
||||||
|
transaction_pool,
|
||||||
|
prometheus_registry.clone(),
|
||||||
|
telemetry.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let relay_chain_backend = relay_chain_node.backend.clone();
|
||||||
|
let relay_chain_client = relay_chain_node.client.clone();
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
cumulus_client_consensus_relay_chain::build_relay_chain_consensus(
|
||||||
|
cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams {
|
||||||
|
para_id: id,
|
||||||
|
proposer_factory,
|
||||||
|
block_import: client.clone(),
|
||||||
|
relay_chain_client: relay_chain_node.client.clone(),
|
||||||
|
relay_chain_backend: relay_chain_node.backend.clone(),
|
||||||
|
create_inherent_data_providers:
|
||||||
|
move |_, (relay_parent, validation_data)| {
|
||||||
|
let parachain_inherent =
|
||||||
|
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client(
|
||||||
|
relay_parent,
|
||||||
|
&relay_chain_client,
|
||||||
|
&*relay_chain_backend,
|
||||||
|
&validation_data,
|
||||||
|
id,
|
||||||
|
);
|
||||||
|
async move {
|
||||||
|
let parachain_inherent =
|
||||||
|
parachain_inherent.ok_or_else(|| {
|
||||||
|
Box::<dyn std::error::Error + Send + Sync>::from(
|
||||||
|
"Failed to create parachain inherent",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(parachain_inherent)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ cumulus-client-consensus-relay-chain = { path = "../../client/consensus/relay-ch
|
|||||||
cumulus-client-network = { path = "../../client/network" }
|
cumulus-client-network = { path = "../../client/network" }
|
||||||
cumulus-client-service = { path = "../../client/service" }
|
cumulus-client-service = { path = "../../client/service" }
|
||||||
cumulus-primitives-core = { path = "../../primitives/core" }
|
cumulus-primitives-core = { path = "../../primitives/core" }
|
||||||
|
cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" }
|
||||||
cumulus-test-runtime = { path = "../runtime" }
|
cumulus-test-runtime = { path = "../runtime" }
|
||||||
cumulus-test-relay-validation-worker-provider = { path = "../relay-validation-worker-provider" }
|
cumulus-test-relay-validation-worker-provider = { path = "../relay-validation-worker-provider" }
|
||||||
|
|
||||||
@@ -60,6 +61,10 @@ jsonrpc-core = "15.1.0"
|
|||||||
futures = { version = "0.3.5" }
|
futures = { version = "0.3.5" }
|
||||||
tokio = { version = "0.2.21", features = ["macros"] }
|
tokio = { version = "0.2.21", features = ["macros"] }
|
||||||
|
|
||||||
|
# Polkadot dependencies
|
||||||
|
polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||||
|
polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||||
|
|
||||||
# Substrate dependencies
|
# Substrate dependencies
|
||||||
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
+22
-1
@@ -232,10 +232,31 @@ where
|
|||||||
prometheus_registry.as_ref(),
|
prometheus_registry.as_ref(),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let relay_chain_client = relay_chain_full_node.client.clone();
|
||||||
|
let relay_chain_backend = relay_chain_full_node.backend.clone();
|
||||||
|
|
||||||
let parachain_consensus = cumulus_client_consensus_relay_chain::RelayChainConsensus::new(
|
let parachain_consensus = cumulus_client_consensus_relay_chain::RelayChainConsensus::new(
|
||||||
para_id,
|
para_id,
|
||||||
proposer_factory,
|
proposer_factory,
|
||||||
|_, _| async { Ok(sp_timestamp::InherentDataProvider::from_system_time()) },
|
move |_, (relay_parent, validation_data)| {
|
||||||
|
let parachain_inherent =
|
||||||
|
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(
|
||||||
|
relay_parent,
|
||||||
|
&*relay_chain_client,
|
||||||
|
&*relay_chain_backend,
|
||||||
|
&validation_data,
|
||||||
|
para_id,
|
||||||
|
);
|
||||||
|
async move {
|
||||||
|
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let parachain_inherent = parachain_inherent.ok_or_else(|| {
|
||||||
|
Box::<dyn std::error::Error + Send + Sync>::from(String::from("error"))
|
||||||
|
})?;
|
||||||
|
Ok((time, parachain_inherent))
|
||||||
|
}
|
||||||
|
},
|
||||||
client.clone(),
|
client.clone(),
|
||||||
relay_chain_full_node.client.clone(),
|
relay_chain_full_node.client.clone(),
|
||||||
relay_chain_full_node.backend.clone(),
|
relay_chain_full_node.backend.clone(),
|
||||||
|
|||||||
Reference in New Issue
Block a user