mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Companion for Substrate#8526 (#2845)
* Update branch * Make it compile * Compile * gate approval-checking logic (#2470) * Fix build * Updates * Fix merge * Adds missing crate * Companion for Substrate#8386 https://github.com/paritytech/substrate/pull/8386 * Fix fix fix * Fix * Fix compilation * Rewrite to `ParachainsInherentDataProvider` * Make it compile * Renamings * Revert stuff * Remove stale file * Guide updates * Update node/core/parachains-inherent/src/lib.rs Co-authored-by: Andronik Ordian <write@reusable.software> * Update node/core/parachains-inherent/src/lib.rs Co-authored-by: Andronik Ordian <write@reusable.software> * Apply suggestions from code review * Reset accidental changes * More * Remove stale file * update Substrate Co-authored-by: Robert Habermeier <rphmeier@gmail.com> Co-authored-by: Andronik Ordian <write@reusable.software> Co-authored-by: parity-processbot <>
This commit is contained in:
Generated
+169
-170
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -56,7 +56,7 @@ members = [
|
|||||||
"node/core/candidate-selection",
|
"node/core/candidate-selection",
|
||||||
"node/core/candidate-validation",
|
"node/core/candidate-validation",
|
||||||
"node/core/chain-api",
|
"node/core/chain-api",
|
||||||
"node/core/proposer",
|
"node/core/parachains-inherent",
|
||||||
"node/core/provisioner",
|
"node/core/provisioner",
|
||||||
"node/core/pvf",
|
"node/core/pvf",
|
||||||
"node/core/runtime-api",
|
"node/core/runtime-api",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
polkadot-primitives = { package = "polkadot-primitives", path = "../primitives" }
|
polkadot-primitives = { path = "../primitives" }
|
||||||
polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../node/primitives" }
|
polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../node/primitives" }
|
||||||
novelpoly = { package = "reed-solomon-novelpoly", version = "1.0.0" }
|
novelpoly = { package = "reed-solomon-novelpoly", version = "1.0.0" }
|
||||||
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["std", "derive"] }
|
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["std", "derive"] }
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "polkadot-node-core-parachains-inherent"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
futures = "0.3.12"
|
||||||
|
futures-timer = "3.0.2"
|
||||||
|
tracing = "0.1.25"
|
||||||
|
thiserror = "1.0.23"
|
||||||
|
async-trait = "0.1.47"
|
||||||
|
polkadot-node-subsystem = { path = "../../subsystem" }
|
||||||
|
polkadot-overseer = { path = "../../overseer" }
|
||||||
|
polkadot-primitives = { path = "../../../primitives" }
|
||||||
|
sp-blockchain = { 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" }
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Polkadot is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! The parachain inherent data provider
|
||||||
|
//!
|
||||||
|
//! Parachain backing and approval is an off-chain process, but the parachain needs to progress on chain as well. To
|
||||||
|
//! make it progress on chain a block producer needs to forward information about the state of a parachain to the
|
||||||
|
//! runtime. This information is forwarded through an inherent to the runtime. Here we provide the
|
||||||
|
//! [`ParachainInherentDataProvider`] that requests the relevant data from the provisioner subsystem and creates the
|
||||||
|
//! the inherent data that the runtime will use to create an inherent.
|
||||||
|
|
||||||
|
#![deny(unused_crate_dependencies, unused_results)]
|
||||||
|
|
||||||
|
use futures::{select, FutureExt};
|
||||||
|
use polkadot_node_subsystem::{
|
||||||
|
messages::{AllMessages, ProvisionerMessage}, SubsystemError,
|
||||||
|
};
|
||||||
|
use polkadot_overseer::OverseerHandler;
|
||||||
|
use polkadot_primitives::v1::{
|
||||||
|
Block, Hash, InherentData as ParachainsInherentData,
|
||||||
|
};
|
||||||
|
use sp_blockchain::HeaderBackend;
|
||||||
|
use sp_runtime::generic::BlockId;
|
||||||
|
use std::time;
|
||||||
|
|
||||||
|
/// How long to wait for the provisioner, before giving up.
|
||||||
|
const PROVISIONER_TIMEOUT: time::Duration = core::time::Duration::from_millis(2500);
|
||||||
|
|
||||||
|
/// Provides the parachains inherent data.
|
||||||
|
pub struct ParachainsInherentDataProvider {
|
||||||
|
inherent_data: ParachainsInherentData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParachainsInherentDataProvider {
|
||||||
|
/// Create a new instance of the [`ParachainsInherentDataProvider`].
|
||||||
|
pub async fn create<C: HeaderBackend<Block>>(
|
||||||
|
client: &C,
|
||||||
|
mut overseer: OverseerHandler,
|
||||||
|
parent: Hash,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let pid = async {
|
||||||
|
let (sender, receiver) = futures::channel::oneshot::channel();
|
||||||
|
overseer.wait_for_activation(parent, sender).await;
|
||||||
|
receiver.await.map_err(|_| Error::ClosedChannelAwaitingActivation)?.map_err(Error::Subsystem)?;
|
||||||
|
|
||||||
|
let (sender, receiver) = futures::channel::oneshot::channel();
|
||||||
|
overseer.send_msg(AllMessages::Provisioner(
|
||||||
|
ProvisionerMessage::RequestInherentData(parent, sender),
|
||||||
|
)).await;
|
||||||
|
|
||||||
|
receiver.await.map_err(|_| Error::ClosedChannelAwaitingInherentData)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut timeout = futures_timer::Delay::new(PROVISIONER_TIMEOUT).fuse();
|
||||||
|
|
||||||
|
let parent_header = match client.header(BlockId::Hash(parent)) {
|
||||||
|
Ok(Some(h)) => h,
|
||||||
|
Ok(None) => return Err(Error::ParentHeaderNotFound(parent)),
|
||||||
|
Err(err) => return Err(Error::Blockchain(err)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = select! {
|
||||||
|
pid = pid.fuse() => pid,
|
||||||
|
_ = timeout => Err(Error::Timeout),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inherent_data = match res {
|
||||||
|
Ok(pd) => ParachainsInherentData {
|
||||||
|
bitfields: pd.bitfields,
|
||||||
|
backed_candidates: pd.backed_candidates,
|
||||||
|
disputes: pd.disputes,
|
||||||
|
parent_header,
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
tracing::debug!(
|
||||||
|
?err,
|
||||||
|
"Could not get provisioner inherent data; injecting default data",
|
||||||
|
);
|
||||||
|
ParachainsInherentData {
|
||||||
|
bitfields: Vec::new(),
|
||||||
|
backed_candidates: Vec::new(),
|
||||||
|
disputes: Vec::new(),
|
||||||
|
parent_header,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Self { inherent_data })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl sp_inherents::InherentDataProvider for ParachainsInherentDataProvider {
|
||||||
|
fn provide_inherent_data(&self, inherent_data: &mut sp_inherents::InherentData) -> Result<(), sp_inherents::Error> {
|
||||||
|
inherent_data.put_data(
|
||||||
|
polkadot_primitives::v1::PARACHAINS_INHERENT_IDENTIFIER,
|
||||||
|
&self.inherent_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn try_handle_error(
|
||||||
|
&self,
|
||||||
|
_: &sp_inherents::InherentIdentifier,
|
||||||
|
_: &[u8],
|
||||||
|
) -> Option<Result<(), sp_inherents::Error>> {
|
||||||
|
// Inherent isn't checked and can not return any error
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Blockchain error")]
|
||||||
|
Blockchain(sp_blockchain::Error),
|
||||||
|
#[error("Timeout: provisioner did not return inherent data after {:?}", PROVISIONER_TIMEOUT)]
|
||||||
|
Timeout,
|
||||||
|
#[error("Could not find the parent header in the blockchain: {:?}", _0)]
|
||||||
|
ParentHeaderNotFound(Hash),
|
||||||
|
#[error("Closed channel from overseer when awaiting activation")]
|
||||||
|
ClosedChannelAwaitingActivation,
|
||||||
|
#[error("Closed channel from provisioner when awaiting inherent data")]
|
||||||
|
ClosedChannelAwaitingInherentData,
|
||||||
|
#[error("Subsystem failed")]
|
||||||
|
Subsystem(SubsystemError),
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "polkadot-node-core-proposer"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
futures = "0.3.12"
|
|
||||||
futures-timer = "3.0.2"
|
|
||||||
tracing = "0.1.25"
|
|
||||||
polkadot-node-subsystem = { path = "../../subsystem" }
|
|
||||||
polkadot-overseer = { path = "../../overseer" }
|
|
||||||
polkadot-primitives = { path = "../../../primitives" }
|
|
||||||
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-core = { 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-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
@@ -1,311 +0,0 @@
|
|||||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Polkadot.
|
|
||||||
|
|
||||||
// Polkadot is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Polkadot is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! The proposer proposes new blocks to include
|
|
||||||
|
|
||||||
#![deny(unused_crate_dependencies, unused_results)]
|
|
||||||
|
|
||||||
use futures::prelude::*;
|
|
||||||
use futures::select;
|
|
||||||
use polkadot_node_subsystem::{
|
|
||||||
jaeger,
|
|
||||||
messages::{AllMessages, ProvisionerInherentData, ProvisionerMessage}, SubsystemError,
|
|
||||||
};
|
|
||||||
use polkadot_overseer::OverseerHandler;
|
|
||||||
use polkadot_primitives::v1::{
|
|
||||||
Block, Hash, Header, InherentData as ParachainsInherentData,
|
|
||||||
};
|
|
||||||
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider};
|
|
||||||
use sc_telemetry::TelemetryHandle;
|
|
||||||
use sp_core::traits::SpawnNamed;
|
|
||||||
use sp_api::{ApiExt, ProvideRuntimeApi};
|
|
||||||
use sp_blockchain::HeaderBackend;
|
|
||||||
use sp_consensus::{Proposal, DisableProofRecording};
|
|
||||||
use sp_inherents::InherentData;
|
|
||||||
use sp_runtime::traits::{DigestFor, HashFor};
|
|
||||||
use sp_transaction_pool::TransactionPool;
|
|
||||||
use prometheus_endpoint::Registry as PrometheusRegistry;
|
|
||||||
use std::{fmt, pin::Pin, sync::Arc, time};
|
|
||||||
|
|
||||||
/// How long proposing can take, before we give up and err out. We need a relatively large timeout
|
|
||||||
/// here as long as we have large payload in statement distribution. Assuming we can reach most
|
|
||||||
/// nodes within two hops, we will take about 2 seconds for transferring statements (data transfer
|
|
||||||
/// only). If necessary, we could be able to reduce this to 3 seconds. To consider: The lower the
|
|
||||||
/// riskier that we will not be able to include a candidate.
|
|
||||||
const PROPOSE_TIMEOUT: core::time::Duration = core::time::Duration::from_millis(4000);
|
|
||||||
|
|
||||||
/// Custom Proposer factory for Polkadot
|
|
||||||
pub struct ProposerFactory<TxPool, Backend, Client> {
|
|
||||||
inner: sc_basic_authorship::ProposerFactory<TxPool, Backend, Client, DisableProofRecording>,
|
|
||||||
overseer: OverseerHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TxPool, Backend, Client> ProposerFactory<TxPool, Backend, Client> {
|
|
||||||
pub fn new(
|
|
||||||
spawn_handle: impl SpawnNamed + 'static,
|
|
||||||
client: Arc<Client>,
|
|
||||||
transaction_pool: Arc<TxPool>,
|
|
||||||
overseer: OverseerHandler,
|
|
||||||
prometheus: Option<&PrometheusRegistry>,
|
|
||||||
telemetry: Option<TelemetryHandle>,
|
|
||||||
) -> Self {
|
|
||||||
ProposerFactory {
|
|
||||||
inner: sc_basic_authorship::ProposerFactory::new(
|
|
||||||
spawn_handle,
|
|
||||||
client,
|
|
||||||
transaction_pool,
|
|
||||||
prometheus,
|
|
||||||
telemetry,
|
|
||||||
),
|
|
||||||
overseer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TxPool, Backend, Client> sp_consensus::Environment<Block>
|
|
||||||
for ProposerFactory<TxPool, Backend, Client>
|
|
||||||
where
|
|
||||||
TxPool: 'static + TransactionPool<Block = Block>,
|
|
||||||
Client: 'static
|
|
||||||
+ BlockBuilderProvider<Backend, Block, Client>
|
|
||||||
+ ProvideRuntimeApi<Block>
|
|
||||||
+ HeaderBackend<Block>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
Client::Api:
|
|
||||||
BlockBuilderApi<Block> + ApiExt<Block>,
|
|
||||||
Backend:
|
|
||||||
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
sp_api::StateBackendFor<Client, Block>: sp_api::StateBackend<HashFor<Block>> + Send,
|
|
||||||
{
|
|
||||||
type CreateProposer = Pin<Box<
|
|
||||||
dyn Future<Output = Result<Self::Proposer, Self::Error>> + Send + 'static,
|
|
||||||
>>;
|
|
||||||
type Proposer = Proposer<TxPool, Backend, Client>;
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn init(&mut self, parent_header: &Header) -> Self::CreateProposer {
|
|
||||||
// create the inner proposer
|
|
||||||
let proposer = self.inner.init(parent_header).into_inner();
|
|
||||||
|
|
||||||
// data to be moved into the future
|
|
||||||
let overseer = self.overseer.clone();
|
|
||||||
let parent_header_hash = parent_header.hash();
|
|
||||||
let parent_header = parent_header.clone();
|
|
||||||
|
|
||||||
async move {
|
|
||||||
Ok(Proposer {
|
|
||||||
inner: proposer?,
|
|
||||||
overseer,
|
|
||||||
parent_header,
|
|
||||||
parent_header_hash,
|
|
||||||
})
|
|
||||||
}.boxed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Custom Proposer for Polkadot.
|
|
||||||
///
|
|
||||||
/// This proposer gets the ProvisionerInherentData and injects it into the wrapped
|
|
||||||
/// proposer's inherent data, then delegates the actual proposal generation.
|
|
||||||
pub struct Proposer<TxPool: TransactionPool<Block = Block>, Backend, Client> {
|
|
||||||
inner: sc_basic_authorship::Proposer<Backend, Block, Client, TxPool, DisableProofRecording>,
|
|
||||||
overseer: OverseerHandler,
|
|
||||||
parent_header: Header,
|
|
||||||
parent_header_hash: Hash,
|
|
||||||
}
|
|
||||||
|
|
||||||
// This impl has the same generic bounds as the Proposer impl.
|
|
||||||
impl<TxPool, Backend, Client> Proposer<TxPool, Backend, Client>
|
|
||||||
where
|
|
||||||
TxPool: 'static + TransactionPool<Block = Block>,
|
|
||||||
Client: 'static
|
|
||||||
+ BlockBuilderProvider<Backend, Block, Client>
|
|
||||||
+ ProvideRuntimeApi<Block>
|
|
||||||
+ HeaderBackend<Block>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
Client::Api:
|
|
||||||
BlockBuilderApi<Block> + ApiExt<Block>,
|
|
||||||
Backend:
|
|
||||||
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
sp_api::StateBackendFor<Client, Block>: sp_api::StateBackend<HashFor<Block>> + Send,
|
|
||||||
{
|
|
||||||
/// Get provisioner inherent data
|
|
||||||
///
|
|
||||||
/// This function has a constant timeout: `PROPOSE_TIMEOUT`.
|
|
||||||
async fn get_provisioner_data(&self) -> Result<ProvisionerInherentData, Error> {
|
|
||||||
// clone this (lightweight) data because we're going to move it into the future
|
|
||||||
let mut overseer = self.overseer.clone();
|
|
||||||
let parent_header_hash = self.parent_header_hash.clone();
|
|
||||||
|
|
||||||
let pid = async {
|
|
||||||
let (sender, receiver) = futures::channel::oneshot::channel();
|
|
||||||
overseer.wait_for_activation(parent_header_hash, sender).await;
|
|
||||||
receiver.await.map_err(|_| Error::ClosedChannelAwaitingActivation)??;
|
|
||||||
|
|
||||||
let (sender, receiver) = futures::channel::oneshot::channel();
|
|
||||||
overseer.send_msg(AllMessages::Provisioner(
|
|
||||||
ProvisionerMessage::RequestInherentData(parent_header_hash, sender),
|
|
||||||
)).await;
|
|
||||||
|
|
||||||
receiver.await.map_err(|_| Error::ClosedChannelAwaitingInherentData)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut timeout = futures_timer::Delay::new(PROPOSE_TIMEOUT).fuse();
|
|
||||||
|
|
||||||
select! {
|
|
||||||
pid = pid.fuse() => pid,
|
|
||||||
_ = timeout => Err(Error::Timeout),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TxPool, Backend, Client> sp_consensus::Proposer<Block> for Proposer<TxPool, Backend, Client>
|
|
||||||
where
|
|
||||||
TxPool: 'static + TransactionPool<Block = Block>,
|
|
||||||
Client: 'static
|
|
||||||
+ BlockBuilderProvider<Backend, Block, Client>
|
|
||||||
+ ProvideRuntimeApi<Block>
|
|
||||||
+ HeaderBackend<Block>
|
|
||||||
+ Send
|
|
||||||
+ Sync,
|
|
||||||
Client::Api:
|
|
||||||
BlockBuilderApi<Block> + ApiExt<Block>,
|
|
||||||
Backend:
|
|
||||||
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
sp_api::StateBackendFor<Client, Block>: sp_api::StateBackend<HashFor<Block>> + Send,
|
|
||||||
{
|
|
||||||
type Transaction = sc_client_api::TransactionFor<Backend, Block>;
|
|
||||||
type Proposal = Pin<Box<
|
|
||||||
dyn Future<Output = Result<Proposal<Block, sp_api::TransactionFor<Client, Block>, ()>, Error>> + Send,
|
|
||||||
>>;
|
|
||||||
type Error = Error;
|
|
||||||
type ProofRecording = DisableProofRecording;
|
|
||||||
type Proof = ();
|
|
||||||
|
|
||||||
fn propose(
|
|
||||||
self,
|
|
||||||
mut inherent_data: InherentData,
|
|
||||||
inherent_digests: DigestFor<Block>,
|
|
||||||
max_duration: time::Duration,
|
|
||||||
block_size_limit: Option<usize>,
|
|
||||||
) -> Self::Proposal {
|
|
||||||
async move {
|
|
||||||
let span = jaeger::Span::new(self.parent_header_hash, "propose");
|
|
||||||
let _span = span.child("get-provisioner");
|
|
||||||
|
|
||||||
let parachains_inherent_data = match self.get_provisioner_data().await {
|
|
||||||
Ok(pd) => ParachainsInherentData {
|
|
||||||
bitfields: pd.bitfields,
|
|
||||||
backed_candidates: pd.backed_candidates,
|
|
||||||
disputes: pd.disputes,
|
|
||||||
parent_header: self.parent_header,
|
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
tracing::warn!(err = ?err, "could not get provisioner inherent data; injecting default data");
|
|
||||||
ParachainsInherentData {
|
|
||||||
bitfields: Vec::new(),
|
|
||||||
backed_candidates: Vec::new(),
|
|
||||||
disputes: Vec::new(),
|
|
||||||
parent_header: self.parent_header,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
drop(_span);
|
|
||||||
|
|
||||||
inherent_data.put_data(
|
|
||||||
polkadot_primitives::v1::PARACHAINS_INHERENT_IDENTIFIER,
|
|
||||||
¶chains_inherent_data,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let _span = span.child("authorship-propose");
|
|
||||||
self.inner
|
|
||||||
.propose(inherent_data, inherent_digests, max_duration, block_size_limit)
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It would have been more ergonomic to use thiserror to derive the
|
|
||||||
// From implementations, Display, and std::error::Error, but unfortunately
|
|
||||||
// one of the wrapped errors (sp_inherents::Error) also
|
|
||||||
// don't impl std::error::Error, which breaks the thiserror derive.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
Consensus(sp_consensus::Error),
|
|
||||||
Blockchain(sp_blockchain::Error),
|
|
||||||
Inherent(sp_inherents::Error),
|
|
||||||
Timeout,
|
|
||||||
ClosedChannelAwaitingActivation,
|
|
||||||
ClosedChannelAwaitingInherentData,
|
|
||||||
Subsystem(SubsystemError)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<sp_consensus::Error> for Error {
|
|
||||||
fn from(e: sp_consensus::Error) -> Error {
|
|
||||||
Error::Consensus(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<sp_blockchain::Error> for Error {
|
|
||||||
fn from(e: sp_blockchain::Error) -> Error {
|
|
||||||
Error::Blockchain(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<sp_inherents::Error> for Error {
|
|
||||||
fn from(e: sp_inherents::Error) -> Error {
|
|
||||||
Error::Inherent(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SubsystemError> for Error {
|
|
||||||
fn from(e: SubsystemError) -> Error {
|
|
||||||
Error::Subsystem(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Consensus(err) => write!(f, "consensus error: {}", err),
|
|
||||||
Self::Blockchain(err) => write!(f, "blockchain error: {}", err),
|
|
||||||
Self::Inherent(err) => write!(f, "inherent error: {:?}", err),
|
|
||||||
Self::Timeout => write!(f, "timeout: provisioner did not return inherent data after {:?}", PROPOSE_TIMEOUT),
|
|
||||||
Self::ClosedChannelAwaitingActivation => write!(f, "closed channel from overseer when awaiting activation"),
|
|
||||||
Self::ClosedChannelAwaitingInherentData => write!(f, "closed channel from provisioner when awaiting inherent data"),
|
|
||||||
Self::Subsystem(err) => write!(f, "subsystem error: {:?}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for Error {
|
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
||||||
match self {
|
|
||||||
Self::Consensus(err) => Some(err),
|
|
||||||
Self::Blockchain(err) => Some(err),
|
|
||||||
Self::Subsystem(err) => Some(err),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -445,7 +445,6 @@ impl OverseerHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for a block with the given hash to be in the active-leaves set.
|
/// Wait for a block with the given hash to be in the active-leaves set.
|
||||||
/// This method is used for external code like `Proposer` that doesn't subscribe to Overseer's signals.
|
|
||||||
///
|
///
|
||||||
/// The response channel responds if the hash was activated and is closed if the hash was deactivated.
|
/// The response channel responds if the hash was activated and is closed if the hash was deactivated.
|
||||||
/// Note that due the fact the overseer doesn't store the whole active-leaves set, only deltas,
|
/// Note that due the fact the overseer doesn't store the whole active-leaves set, only deltas,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "
|
|||||||
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus-uncles = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
@@ -22,12 +23,12 @@ sc-finality-grandpa-warp-sync = { git = "https://github.com/paritytech/substrate
|
|||||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" }
|
telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
# Substrate Primitives
|
# Substrate Primitives
|
||||||
sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
@@ -43,6 +44,8 @@ sp-session = { git = "https://github.com/paritytech/substrate", branch = "master
|
|||||||
sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
# Substrate Pallets
|
# Substrate Pallets
|
||||||
@@ -67,7 +70,7 @@ kvdb = "0.9.0"
|
|||||||
kvdb-rocksdb = { version = "0.11.0", optional = true }
|
kvdb-rocksdb = { version = "0.11.0", optional = true }
|
||||||
|
|
||||||
# Polkadot
|
# Polkadot
|
||||||
polkadot-node-core-proposer = { path = "../core/proposer" }
|
polkadot-node-core-parachains-inherent = { path = "../core/parachains-inherent" }
|
||||||
polkadot-overseer = { path = "../overseer" }
|
polkadot-overseer = { path = "../overseer" }
|
||||||
polkadot-parachain = { path = "../../parachain" }
|
polkadot-parachain = { path = "../../parachain" }
|
||||||
polkadot-primitives = { path = "../../primitives" }
|
polkadot-primitives = { path = "../../primitives" }
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use rococo::constants::size::MAX_CODE_SIZE;
|
use rococo::constants::size::MAX_CODE_SIZE;
|
||||||
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
||||||
use babe_primitives::AuthorityId as BabeId;
|
use sp_consensus_babe::AuthorityId as BabeId;
|
||||||
use beefy_primitives::ecdsa::AuthorityId as BeefyId;
|
use beefy_primitives::ecdsa::AuthorityId as BeefyId;
|
||||||
use grandpa::AuthorityId as GrandpaId;
|
use grandpa::AuthorityId as GrandpaId;
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use consensus_common::BlockStatus;
|
|||||||
pub trait RuntimeApiCollection:
|
pub trait RuntimeApiCollection:
|
||||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||||
+ sp_api::ApiExt<Block>
|
+ sp_api::ApiExt<Block>
|
||||||
+ babe_primitives::BabeApi<Block>
|
+ sp_consensus_babe::BabeApi<Block>
|
||||||
+ grandpa_primitives::GrandpaApi<Block>
|
+ grandpa_primitives::GrandpaApi<Block>
|
||||||
+ ParachainHost<Block>
|
+ ParachainHost<Block>
|
||||||
+ sp_block_builder::BlockBuilder<Block>
|
+ sp_block_builder::BlockBuilder<Block>
|
||||||
@@ -52,7 +52,7 @@ impl<Api> RuntimeApiCollection for Api
|
|||||||
where
|
where
|
||||||
Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||||
+ sp_api::ApiExt<Block>
|
+ sp_api::ApiExt<Block>
|
||||||
+ babe_primitives::BabeApi<Block>
|
+ sp_consensus_babe::BabeApi<Block>
|
||||||
+ grandpa_primitives::GrandpaApi<Block>
|
+ grandpa_primitives::GrandpaApi<Block>
|
||||||
+ ParachainHost<Block>
|
+ ParachainHost<Block>
|
||||||
+ sp_block_builder::BlockBuilder<Block>
|
+ sp_block_builder::BlockBuilder<Block>
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ use {
|
|||||||
polkadot_node_core_av_store::Error as AvailabilityError,
|
polkadot_node_core_av_store::Error as AvailabilityError,
|
||||||
polkadot_node_core_approval_voting::Config as ApprovalVotingConfig,
|
polkadot_node_core_approval_voting::Config as ApprovalVotingConfig,
|
||||||
polkadot_node_core_candidate_validation::Config as CandidateValidationConfig,
|
polkadot_node_core_candidate_validation::Config as CandidateValidationConfig,
|
||||||
polkadot_node_core_proposer::ProposerFactory,
|
|
||||||
polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandler},
|
polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandler},
|
||||||
polkadot_primitives::v1::ParachainHost,
|
polkadot_primitives::v1::ParachainHost,
|
||||||
sc_authority_discovery::Service as AuthorityDiscoveryService,
|
sc_authority_discovery::Service as AuthorityDiscoveryService,
|
||||||
@@ -41,7 +40,7 @@ use {
|
|||||||
sp_trie::PrefixedMemoryDB,
|
sp_trie::PrefixedMemoryDB,
|
||||||
sc_client_api::{AuxStore, ExecutorProvider},
|
sc_client_api::{AuxStore, ExecutorProvider},
|
||||||
sc_keystore::LocalKeystore,
|
sc_keystore::LocalKeystore,
|
||||||
babe_primitives::BabeApi,
|
sp_consensus_babe::BabeApi,
|
||||||
grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider},
|
grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider},
|
||||||
beefy_primitives::ecdsa::AuthoritySignature as BeefySignature,
|
beefy_primitives::ecdsa::AuthoritySignature as BeefySignature,
|
||||||
sp_runtime::traits::Header as HeaderT,
|
sp_runtime::traits::Header as HeaderT,
|
||||||
@@ -263,8 +262,6 @@ fn new_partial<RuntimeApi, Executor>(
|
|||||||
set_prometheus_registry(config)?;
|
set_prometheus_registry(config)?;
|
||||||
|
|
||||||
|
|
||||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
|
||||||
|
|
||||||
let telemetry = config.telemetry_endpoints.clone()
|
let telemetry = config.telemetry_endpoints.clone()
|
||||||
.filter(|x| !x.is_empty())
|
.filter(|x| !x.is_empty())
|
||||||
.map(move |endpoints| -> Result<_, telemetry::Error> {
|
.map(move |endpoints| -> Result<_, telemetry::Error> {
|
||||||
@@ -331,13 +328,24 @@ fn new_partial<RuntimeApi, Executor>(
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let slot_duration = babe_link.config().slot_duration();
|
||||||
let import_queue = babe::import_queue(
|
let import_queue = babe::import_queue(
|
||||||
babe_link.clone(),
|
babe_link.clone(),
|
||||||
block_import.clone(),
|
block_import.clone(),
|
||||||
Some(Box::new(justification_import)),
|
Some(Box::new(justification_import)),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
select_chain.clone(),
|
select_chain.clone(),
|
||||||
inherent_data_providers.clone(),
|
move |_, ()| async move {
|
||||||
|
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*timestamp,
|
||||||
|
slot_duration,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((timestamp, slot))
|
||||||
|
},
|
||||||
&task_manager.spawn_essential_handle(),
|
&task_manager.spawn_essential_handle(),
|
||||||
config.prometheus_registry(),
|
config.prometheus_registry(),
|
||||||
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
||||||
@@ -407,7 +415,6 @@ fn new_partial<RuntimeApi, Executor>(
|
|||||||
select_chain,
|
select_chain,
|
||||||
import_queue,
|
import_queue,
|
||||||
transaction_pool,
|
transaction_pool,
|
||||||
inherent_data_providers,
|
|
||||||
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry)
|
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -708,7 +715,6 @@ pub fn new_full<RuntimeApi, Executor>(
|
|||||||
select_chain,
|
select_chain,
|
||||||
import_queue,
|
import_queue,
|
||||||
transaction_pool,
|
transaction_pool,
|
||||||
inherent_data_providers,
|
|
||||||
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry)
|
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry)
|
||||||
} = new_partial::<RuntimeApi, Executor>(&mut config, jaeger_agent, telemetry_worker_handle)?;
|
} = new_partial::<RuntimeApi, Executor>(&mut config, jaeger_agent, telemetry_worker_handle)?;
|
||||||
|
|
||||||
@@ -893,21 +899,25 @@ pub fn new_full<RuntimeApi, Executor>(
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
Some(overseer_handler)
|
Some(overseer_handler)
|
||||||
} else { None };
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if role.is_authority() {
|
if role.is_authority() {
|
||||||
let can_author_with =
|
let can_author_with =
|
||||||
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
|
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
|
||||||
|
|
||||||
let proposer = ProposerFactory::new(
|
let proposer = sc_basic_authorship::ProposerFactory::new(
|
||||||
task_manager.spawn_handle(),
|
task_manager.spawn_handle(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
transaction_pool,
|
transaction_pool,
|
||||||
overseer_handler.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone(),
|
|
||||||
prometheus_registry.as_ref(),
|
prometheus_registry.as_ref(),
|
||||||
telemetry.as_ref().map(|x| x.handle()),
|
telemetry.as_ref().map(|x| x.handle()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let client_clone = client.clone();
|
||||||
|
let overseer_handler = overseer_handler.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone();
|
||||||
|
let slot_duration = babe_link.config().slot_duration();
|
||||||
let babe_config = babe::BabeParams {
|
let babe_config = babe::BabeParams {
|
||||||
keystore: keystore_container.sync_keystore(),
|
keystore: keystore_container.sync_keystore(),
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
@@ -915,7 +925,32 @@ pub fn new_full<RuntimeApi, Executor>(
|
|||||||
block_import,
|
block_import,
|
||||||
env: proposer,
|
env: proposer,
|
||||||
sync_oracle: network.clone(),
|
sync_oracle: network.clone(),
|
||||||
inherent_data_providers: inherent_data_providers.clone(),
|
create_inherent_data_providers: move |parent, ()| {
|
||||||
|
let client_clone = client_clone.clone();
|
||||||
|
let overseer_handler = overseer_handler.clone();
|
||||||
|
async move {
|
||||||
|
let parachain = polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::create(
|
||||||
|
&*client_clone,
|
||||||
|
overseer_handler,
|
||||||
|
parent,
|
||||||
|
).await.map_err(|e| Box::new(e))?;
|
||||||
|
|
||||||
|
let uncles = sc_consensus_uncles::create_uncles_inherent_data_provider(
|
||||||
|
&*client_clone,
|
||||||
|
parent,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*timestamp,
|
||||||
|
slot_duration,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((timestamp, slot, uncles, parachain))
|
||||||
|
}
|
||||||
|
},
|
||||||
force_authoring,
|
force_authoring,
|
||||||
backoff_authoring_blocks,
|
backoff_authoring_blocks,
|
||||||
babe_link,
|
babe_link,
|
||||||
@@ -1096,16 +1131,25 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
|
||||||
|
|
||||||
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
||||||
|
let slot_duration = babe_link.config().slot_duration();
|
||||||
let import_queue = babe::import_queue(
|
let import_queue = babe::import_queue(
|
||||||
babe_link,
|
babe_link,
|
||||||
babe_block_import,
|
babe_block_import,
|
||||||
Some(Box::new(justification_import)),
|
Some(Box::new(justification_import)),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
select_chain.clone(),
|
select_chain.clone(),
|
||||||
inherent_data_providers.clone(),
|
move |_, ()| async move {
|
||||||
|
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*timestamp,
|
||||||
|
slot_duration,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((timestamp, slot))
|
||||||
|
},
|
||||||
&task_manager.spawn_essential_handle(),
|
&task_manager.spawn_essential_handle(),
|
||||||
config.prometheus_registry(),
|
config.prometheus_registry(),
|
||||||
consensus_common::NeverCanAuthor,
|
consensus_common::NeverCanAuthor,
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ sequenceDiagram
|
|||||||
participant CB as CandidateBacking
|
participant CB as CandidateBacking
|
||||||
participant BD as BitfieldDistribution
|
participant BD as BitfieldDistribution
|
||||||
participant RA as RuntimeApi
|
participant RA as RuntimeApi
|
||||||
participant PO as Proposer
|
participant PI as ParachainsInherentDataProvider
|
||||||
|
|
||||||
alt receive provisionable data
|
alt receive provisionable data
|
||||||
alt
|
alt
|
||||||
@@ -395,33 +395,24 @@ sequenceDiagram
|
|||||||
|
|
||||||
Note over PV: store bitfields and backed candidates
|
Note over PV: store bitfields and backed candidates
|
||||||
else receive request for inherent data
|
else receive request for inherent data
|
||||||
PO ->> PV: RequestInherentData
|
PI ->> PV: RequestInherentData
|
||||||
alt we have already constructed the inherent data
|
alt we have already constructed the inherent data
|
||||||
PV ->> PO: send the inherent data
|
PV ->> PI: send the inherent data
|
||||||
else we have not yet constructed the inherent data
|
else we have not yet constructed the inherent data
|
||||||
Note over PV,PO: Store the return sender without sending immediately
|
Note over PV,PI: Store the return sender without sending immediately
|
||||||
end
|
end
|
||||||
else timer times out
|
else timer times out
|
||||||
note over PV: Waited 2 seconds
|
note over PV: Waited 2 seconds
|
||||||
PV -->> RA: RuntimeApiRequest::AvailabilityCores
|
PV -->> RA: RuntimeApiRequest::AvailabilityCores
|
||||||
Note over PV: construct and store the inherent data
|
Note over PV: construct and store the inherent data
|
||||||
loop over stored inherent data requests
|
loop over stored inherent data requests
|
||||||
PV ->> PO: (SignedAvailabilityBitfields, BackedCandidates)
|
PV ->> PI: (SignedAvailabilityBitfields, BackedCandidates)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
In principle, any arbitrary subsystem could send a `RequestInherentData` to the `Provisioner`. In practice,
|
In principle, any arbitrary subsystem could send a `RequestInherentData` to the `Provisioner`. In practice,
|
||||||
only the `Proposer` does so.
|
only the `ParachainsInherentDataProvider` does so.
|
||||||
|
|
||||||
The proposer is an atypical subsystem in that, unlike most of them, it is not primarily driven by
|
The tuple `(SignedAvailabilityBitfields, BackedCandidates, ParentHeader)` is injected by the `ParachainsInherentDataProvider`
|
||||||
the `Overseer`, but instead by the `sp_consensus::Environment` and `sp_consensus::Proposer` traits
|
|
||||||
from Substrate. It doesn't make much sense to diagram this flow because it's very linear:
|
|
||||||
|
|
||||||
- Substrate creates a `Proposer` from the `ProposerFactory` once per upcoming block, using the `parent_header: Header`.
|
|
||||||
- At some later point, it calls `Proposer::propose(self, ...)`, consuming the proposer to generate a proposal
|
|
||||||
- `Proposer::propose` sends a `RequestInherentData` to the `Provisioner`. This has a fixed timeout of
|
|
||||||
2.5 seconds, meaning that the provisioner has approximately 0.5 seconds to generate and send the data.
|
|
||||||
|
|
||||||
The tuple `(SignedAvailabilityBitfields, BackedCandidates, ParentHeader)` is injected by the `Proposer`
|
|
||||||
into the inherent data. From that point on, control passes from the node to the runtime.
|
into the inherent data. From that point on, control passes from the node to the runtime.
|
||||||
|
|||||||
@@ -564,9 +564,6 @@ enum ProvisionerMessage {
|
|||||||
/// advancing the state of parachain consensus in a block building upon the given hash.
|
/// advancing the state of parachain consensus in a block building upon the given hash.
|
||||||
///
|
///
|
||||||
/// If called at different points in time, this may give different results.
|
/// If called at different points in time, this may give different results.
|
||||||
///
|
|
||||||
/// This is expected to be used by a proposer, to inject that information into the InherentData
|
|
||||||
/// where it can be assembled into the ParaInherent.
|
|
||||||
RequestInherentData(Hash, oneshot::Sender<ParaInherentData>),
|
RequestInherentData(Hash, oneshot::Sender<ParaInherentData>),
|
||||||
/// This data should become part of a relay chain block
|
/// This data should become part of a relay chain block
|
||||||
ProvisionableData(ProvisionableData),
|
ProvisionableData(ProvisionableData),
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substra
|
|||||||
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
frame-support-test = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
frame-support-test = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
serde_json = "1.0.61"
|
serde_json = "1.0.61"
|
||||||
libsecp256k1 = "0.3.5"
|
libsecp256k1 = "0.3.5"
|
||||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ use frame_support::{
|
|||||||
dispatch::DispatchResultWithPostInfo,
|
dispatch::DispatchResultWithPostInfo,
|
||||||
weights::{DispatchClass, Weight},
|
weights::{DispatchClass, Weight},
|
||||||
traits::Get,
|
traits::Get,
|
||||||
|
inherent::{InherentIdentifier, InherentData, MakeFatalError, ProvideInherent},
|
||||||
};
|
};
|
||||||
use frame_system::ensure_none;
|
use frame_system::ensure_none;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -38,7 +39,6 @@ use crate::{
|
|||||||
scheduler::{self, FreedReason},
|
scheduler::{self, FreedReason},
|
||||||
ump,
|
ump,
|
||||||
};
|
};
|
||||||
use inherents::{InherentIdentifier, InherentData, MakeFatalError, ProvideInherent};
|
|
||||||
|
|
||||||
const LOG_TARGET: &str = "runtime::inclusion-inherent";
|
const LOG_TARGET: &str = "runtime::inclusion-inherent";
|
||||||
// In the future, we should benchmark these consts; these are all untested assumptions for now.
|
// In the future, we should benchmark these consts; these are all untested assumptions for now.
|
||||||
|
|||||||
Reference in New Issue
Block a user