// 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 .
//! The block production pipeline of Polkadot.
//!
//! The `ProposerFactory` exported by this module will be wrapped by some
//! consensus engine, and triggered when it is time to create a block.
use std::{
pin::Pin,
sync::Arc,
time::Duration,
};
use sp_blockchain::HeaderBackend;
use block_builder::{BlockBuilderApi, BlockBuilderProvider};
use consensus::{Proposal, RecordProof};
use polkadot_primitives::v0::{NEW_HEADS_IDENTIFIER, Block, Header, AttestedCandidate};
use runtime_primitives::traits::{DigestFor, HashFor};
use txpool_api::TransactionPool;
use futures::prelude::*;
use inherents::InherentData;
use sp_api::{ApiExt, ProvideRuntimeApi};
use prometheus_endpoint::Registry as PrometheusRegistry;
use crate::Error;
// Polkadot proposer factory.
pub struct ProposerFactory {
factory: sc_basic_authorship::ProposerFactory,
}
impl ProposerFactory {
/// Create a new proposer factory.
pub fn new(
client: Arc,
transaction_pool: Arc,
prometheus: Option<&PrometheusRegistry>,
) -> Self {
let factory = sc_basic_authorship::ProposerFactory::new(
client,
transaction_pool,
prometheus,
);
ProposerFactory {
factory,
}
}
}
impl consensus::Environment
for ProposerFactory
where
TxPool: TransactionPool + 'static,
Client: BlockBuilderProvider + ProvideRuntimeApi + HeaderBackend + Send + Sync + 'static,
Client::Api: BlockBuilderApi
+ ApiExt,
Backend: sc_client_api::Backend<
Block,
State = sp_api::StateBackendFor
> + 'static,
// Rust bug: https://github.com/rust-lang/rust/issues/24159
sp_api::StateBackendFor: sp_api::StateBackend> + Send,
{
type CreateProposer = Pin> + Send + 'static
>>;
type Proposer = Proposer;
type Error = Error;
fn init(
&mut self,
parent_header: &Header,
) -> Self::CreateProposer {
let proposer = self.factory.init(parent_header)
.into_inner()
.map_err(Into::into)
.map(|proposer| Proposer { proposer });
Box::pin(future::ready(proposer))
}
}
/// The Polkadot proposer logic.
pub struct Proposer, Backend> {
proposer: sc_basic_authorship::Proposer,
}
impl consensus::Proposer for Proposer where
TxPool: TransactionPool + 'static,
Client: BlockBuilderProvider + ProvideRuntimeApi + HeaderBackend + Send + Sync + 'static,
Client::Api: BlockBuilderApi + ApiExt,
Backend: sc_client_api::Backend> + 'static,
// Rust bug: https://github.com/rust-lang/rust/issues/24159
sp_api::StateBackendFor: sp_api::StateBackend> + Send,
{
type Error = Error;
type Transaction = sp_api::TransactionFor;
type Proposal = Pin<
Box<
dyn Future