reuse polkadot-service code (#1273)

This commit is contained in:
Svyatoslav Nikolsky
2022-01-13 16:42:36 +03:00
committed by Bastian Köcher
parent 1d99ad3619
commit 1ec2edd357
7 changed files with 56 additions and 1236 deletions
+1 -29
View File
@@ -50,7 +50,6 @@ sc-consensus-uncles = { git = "https://github.com/paritytech/substrate", branch
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-finality-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
#sc-finality-grandpa-warp-sync = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -77,37 +76,10 @@ substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate
# Polkadot Dependencies
polkadot-client = { git = "https://github.com/paritytech/polkadot", branch = "master" }
# Polkadot (parachain) Dependencies
polkadot-approval-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-availability-bitfield-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-availability-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-availability-recovery = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-collator-protocol = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-dispute-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-gossip-support = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-network-bridge = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-collation-generation = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-approval-voting = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-av-store = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-backing = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-bitfield-signing = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-candidate-validation = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-chain-api = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-chain-selection = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-parachains-inherent = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-provisioner = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-pvf = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-runtime-api = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-core-dispute-coordinator = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-network-protocol = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-node-subsystem-util = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-statement-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false, features = [ "full-node", "polkadot-native" ] }
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
+4 -3
View File
@@ -30,7 +30,8 @@ use sp_finality_grandpa::AuthorityId as GrandpaId;
use sp_runtime::traits::{IdentifyAccount, Verify};
/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;
pub type ChainSpec =
sc_service::GenericChainSpec<GenesisConfig, polkadot_service::chain_spec::Extensions>;
/// The chain specification option. This is expected to come in from the CLI and
/// is little more than one of a number of alternatives which can easily be converted
@@ -104,7 +105,7 @@ impl Alternative {
None,
None,
properties,
None,
Default::default(),
),
Alternative::LocalTestnet => ChainSpec::from_genesis(
"Rialto Local",
@@ -128,7 +129,7 @@ impl Alternative {
None,
None,
properties,
None,
Default::default(),
),
}
}
+51 -24
View File
@@ -14,13 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use crate::{
cli::{Cli, Subcommand},
service::new_partial,
};
use crate::cli::{Cli, Subcommand};
use rialto_runtime::{Block, RuntimeApi};
use sc_cli::{ChainSpec, Role, RuntimeVersion, SubstrateCli};
use sc_service::PartialComponents;
impl SubstrateCli for Cli {
fn impl_name() -> String {
@@ -67,6 +63,21 @@ impl SubstrateCli for Cli {
}
}
// Rialto native executor instance.
pub struct ExecutorDispatch;
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
rialto_runtime::api::dispatch(method, data)
}
fn native_version() -> sc_executor::NativeVersion {
rialto_runtime::native_version()
}
}
/// Parse and run command line arguments
pub fn run() -> sc_cli::Result<()> {
let cli = Cli::from_args();
@@ -79,7 +90,7 @@ pub fn run() -> sc_cli::Result<()> {
if cfg!(feature = "runtime-benchmarks") {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<Block, crate::service::ExecutorDispatch>(config))
runner.sync_run(|config| cmd.run::<Block, ExecutorDispatch>(config))
} else {
println!(
"Benchmarking wasn't enabled when building the node. \
@@ -98,32 +109,32 @@ pub fn run() -> sc_cli::Result<()> {
Some(Subcommand::CheckBlock(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|mut config| {
let PartialComponents { client, task_manager, import_queue, .. } =
new_partial(&mut config).map_err(service_error)?;
let (client, _, import_queue, task_manager) =
polkadot_service::new_chain_ops(&mut config, None).map_err(service_error)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
Some(Subcommand::ExportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|mut config| {
let PartialComponents { client, task_manager, .. } =
new_partial(&mut config).map_err(service_error)?;
let (client, _, _, task_manager) =
polkadot_service::new_chain_ops(&mut config, None).map_err(service_error)?;
Ok((cmd.run(client, config.database), task_manager))
})
},
Some(Subcommand::ExportState(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|mut config| {
let PartialComponents { client, task_manager, .. } =
new_partial(&mut config).map_err(service_error)?;
let (client, _, _, task_manager) =
polkadot_service::new_chain_ops(&mut config, None).map_err(service_error)?;
Ok((cmd.run(client, config.chain_spec), task_manager))
})
},
Some(Subcommand::ImportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|mut config| {
let PartialComponents { client, task_manager, import_queue, .. } =
new_partial(&mut config).map_err(service_error)?;
let (client, _, import_queue, task_manager) =
polkadot_service::new_chain_ops(&mut config, None).map_err(service_error)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
@@ -134,16 +145,14 @@ pub fn run() -> sc_cli::Result<()> {
Some(Subcommand::Revert(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|mut config| {
let PartialComponents { client, task_manager, backend, .. } =
new_partial(&mut config).map_err(service_error)?;
let (client, backend, _, task_manager) =
polkadot_service::new_chain_ops(&mut config, None).map_err(service_error)?;
Ok((cmd.run(client, backend), task_manager))
})
},
Some(Subcommand::Inspect(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| {
cmd.run::<Block, RuntimeApi, crate::service::ExecutorDispatch>(config)
})
runner.sync_run(|config| cmd.run::<Block, RuntimeApi, ExecutorDispatch>(config))
},
Some(Subcommand::PvfPrepareWorker(cmd)) => {
let mut builder = sc_cli::LoggerBuilder::new("");
@@ -170,15 +179,33 @@ pub fn run() -> sc_cli::Result<()> {
// let no_beefy = true;
// let telemetry_worker_handler = None;
// let is_collator = crate::service::IsCollator::No;
let overseer_gen = crate::overseer::RealOverseerGen;
let overseer_gen = polkadot_service::overseer::RealOverseerGen;
runner.run_node_until_exit(|config| async move {
match config.role {
Role::Light => Err(sc_cli::Error::Service(sc_service::Error::Other(
"Light client is not supported by this node".into(),
))),
_ => crate::service::build_full(config, overseer_gen)
.map(|full| full.task_manager)
.map_err(service_error),
_ => {
let is_collator = polkadot_service::IsCollator::No;
let grandpa_pause = None;
let enable_beefy = true;
let jaeger_agent = None;
let telemetry_worker_handle = None;
let program_path = None;
polkadot_service::new_full::<rialto_runtime::RuntimeApi, ExecutorDispatch, _>(
config,
is_collator,
grandpa_pause,
enable_beefy,
jaeger_agent,
telemetry_worker_handle,
program_path,
overseer_gen,
)
.map(|full| full.task_manager)
.map_err(service_error)
},
}
})
},
@@ -187,6 +214,6 @@ pub fn run() -> sc_cli::Result<()> {
// We don't want to change 'service.rs' too much to ease future updates => it'll keep using
// its own error enum like original polkadot service does.
fn service_error(err: crate::service::Error) -> sc_cli::Error {
fn service_error(err: polkadot_service::Error) -> sc_cli::Error {
sc_cli::Error::Application(Box::new(err))
}
-4
View File
@@ -19,12 +19,8 @@
#![warn(missing_docs)]
mod chain_spec;
#[macro_use]
mod service;
mod cli;
mod command;
mod overseer;
mod parachains_db;
/// Run the Rialto Node
fn main() -> sc_cli::Result<()> {
-316
View File
@@ -1,316 +0,0 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common 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.
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! This is almost 1:1 copy of `node/service/src/overseer.rs` file from Polkadot repository.
//! The only exception is that we don't support db upgrades => no `upgrade.rs` module.
// this warning comes from `polkadot_overseer::AllSubsystems` type
#![allow(clippy::type_complexity)]
use crate::service::{AuthorityDiscoveryApi, Error};
use rialto_runtime::{opaque::Block, Hash};
use lru::LruCache;
use polkadot_availability_distribution::IncomingRequestReceivers;
use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
use polkadot_node_core_av_store::Config as AvailabilityConfig;
use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig;
use polkadot_node_core_chain_selection::Config as ChainSelectionConfig;
use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
use polkadot_node_network_protocol::request_response::{v1 as request_v1, IncomingRequestReceiver};
use polkadot_overseer::{
metrics::Metrics as OverseerMetrics, BlockInfo, MetricsTrait, Overseer, OverseerBuilder,
OverseerConnector, OverseerHandle,
};
use polkadot_primitives::v1::ParachainHost;
use sc_authority_discovery::Service as AuthorityDiscoveryService;
use sc_client_api::AuxStore;
use sc_keystore::LocalKeystore;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_consensus_babe::BabeApi;
use sp_core::traits::SpawnNamed;
use std::sync::Arc;
use substrate_prometheus_endpoint::Registry;
pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem;
pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem;
pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem;
pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide};
pub use polkadot_dispute_distribution::DisputeDistributionSubsystem;
pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem;
pub use polkadot_network_bridge::NetworkBridge as NetworkBridgeSubsystem;
pub use polkadot_node_collation_generation::CollationGenerationSubsystem;
pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem;
pub use polkadot_node_core_av_store::AvailabilityStoreSubsystem;
pub use polkadot_node_core_backing::CandidateBackingSubsystem;
pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem;
pub use polkadot_node_core_candidate_validation::CandidateValidationSubsystem;
pub use polkadot_node_core_chain_api::ChainApiSubsystem;
pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem;
pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem;
pub use polkadot_node_core_provisioner::ProvisionerSubsystem;
pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem;
pub use polkadot_statement_distribution::StatementDistribution as StatementDistributionSubsystem;
/// Arguments passed for overseer construction.
pub struct OverseerGenArgs<'a, Spawner, RuntimeClient>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
/// Set of initial relay chain leaves to track.
pub leaves: Vec<BlockInfo>,
/// The keystore to use for i.e. validator keys.
pub keystore: Arc<LocalKeystore>,
/// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others.
pub runtime_client: Arc<RuntimeClient>,
/// The underlying key value store for the parachains.
pub parachains_db: Arc<dyn kvdb::KeyValueDB>,
/// Underlying network service implementation.
pub network_service: Arc<sc_network::NetworkService<Block, Hash>>,
/// Underlying authority discovery service.
pub authority_discovery_service: AuthorityDiscoveryService,
/// POV request receiver
pub pov_req_receiver: IncomingRequestReceiver<request_v1::PoVFetchingRequest>,
pub chunk_req_receiver: IncomingRequestReceiver<request_v1::ChunkFetchingRequest>,
pub collation_req_receiver: IncomingRequestReceiver<request_v1::CollationFetchingRequest>,
pub available_data_req_receiver:
IncomingRequestReceiver<request_v1::AvailableDataFetchingRequest>,
pub statement_req_receiver: IncomingRequestReceiver<request_v1::StatementFetchingRequest>,
pub dispute_req_receiver: IncomingRequestReceiver<request_v1::DisputeRequest>,
/// Prometheus registry, commonly used for production systems, less so for test.
pub registry: Option<&'a Registry>,
/// Task spawner to be used throughout the overseer and the APIs it provides.
pub spawner: Spawner,
/// Configuration for the approval voting subsystem.
pub approval_voting_config: ApprovalVotingConfig,
/// Configuration for the availability store subsystem.
pub availability_config: AvailabilityConfig,
/// Configuration for the candidate validation subsystem.
pub candidate_validation_config: CandidateValidationConfig,
/// Configuration for the chain selection subsystem.
pub chain_selection_config: ChainSelectionConfig,
/// Configuration for the dispute coordinator subsystem.
pub dispute_coordinator_config: DisputeCoordinatorConfig,
}
/// Obtain a prepared `OverseerBuilder`, that is initialized
/// with all default values.
pub fn prepared_overseer_builder<Spawner, RuntimeClient>(
OverseerGenArgs {
leaves,
keystore,
runtime_client,
parachains_db,
network_service,
authority_discovery_service,
pov_req_receiver,
chunk_req_receiver,
collation_req_receiver: _,
available_data_req_receiver,
statement_req_receiver,
dispute_req_receiver,
registry,
spawner,
approval_voting_config,
availability_config,
candidate_validation_config,
chain_selection_config,
dispute_coordinator_config,
}: OverseerGenArgs<'_, Spawner, RuntimeClient>,
) -> Result<
OverseerBuilder<
Spawner,
Arc<RuntimeClient>,
CandidateValidationSubsystem,
CandidateBackingSubsystem<Spawner>,
StatementDistributionSubsystem,
AvailabilityDistributionSubsystem,
AvailabilityRecoverySubsystem,
BitfieldSigningSubsystem<Spawner>,
BitfieldDistributionSubsystem,
ProvisionerSubsystem<Spawner>,
RuntimeApiSubsystem<RuntimeClient>,
AvailabilityStoreSubsystem,
NetworkBridgeSubsystem<
Arc<sc_network::NetworkService<Block, Hash>>,
AuthorityDiscoveryService,
>,
ChainApiSubsystem<RuntimeClient>,
CollationGenerationSubsystem,
CollatorProtocolSubsystem,
ApprovalDistributionSubsystem,
ApprovalVotingSubsystem,
GossipSupportSubsystem<AuthorityDiscoveryService>,
DisputeCoordinatorSubsystem,
DisputeDistributionSubsystem<AuthorityDiscoveryService>,
ChainSelectionSubsystem,
>,
Error,
>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
use polkadot_node_subsystem_util::metrics::Metrics;
use std::iter::FromIterator;
let metrics = <OverseerMetrics as MetricsTrait>::register(registry)?;
let builder = Overseer::builder()
.availability_distribution(AvailabilityDistributionSubsystem::new(
keystore.clone(),
IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver },
Metrics::register(registry)?,
))
.availability_recovery(AvailabilityRecoverySubsystem::with_chunks_only(
available_data_req_receiver,
Metrics::register(registry)?,
))
.availability_store(AvailabilityStoreSubsystem::new(
parachains_db.clone(),
availability_config,
Metrics::register(registry)?,
))
.bitfield_distribution(BitfieldDistributionSubsystem::new(Metrics::register(registry)?))
.bitfield_signing(BitfieldSigningSubsystem::new(
spawner.clone(),
keystore.clone(),
Metrics::register(registry)?,
))
.candidate_backing(CandidateBackingSubsystem::new(
spawner.clone(),
keystore.clone(),
Metrics::register(registry)?,
))
.candidate_validation(CandidateValidationSubsystem::with_config(
candidate_validation_config,
Metrics::register(registry)?, // candidate-validation metrics
Metrics::register(registry)?, // validation host metrics
))
.chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?))
.collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?))
.collator_protocol(CollatorProtocolSubsystem::new(ProtocolSide::Validator {
keystore: keystore.clone(),
eviction_policy: Default::default(),
metrics: Metrics::register(registry)?,
}))
.network_bridge(NetworkBridgeSubsystem::new(
network_service.clone(),
authority_discovery_service.clone(),
Box::new(network_service.clone()),
Metrics::register(registry)?,
))
.provisioner(ProvisionerSubsystem::new(spawner.clone(), (), Metrics::register(registry)?))
.runtime_api(RuntimeApiSubsystem::new(
runtime_client.clone(),
Metrics::register(registry)?,
spawner.clone(),
))
.statement_distribution(StatementDistributionSubsystem::new(
keystore.clone(),
statement_req_receiver,
Metrics::register(registry)?,
))
.approval_distribution(ApprovalDistributionSubsystem::new(Metrics::register(registry)?))
.approval_voting(ApprovalVotingSubsystem::with_config(
approval_voting_config,
parachains_db.clone(),
keystore.clone(),
Box::new(network_service),
Metrics::register(registry)?,
))
.gossip_support(GossipSupportSubsystem::new(
keystore.clone(),
authority_discovery_service.clone(),
))
.dispute_coordinator(DisputeCoordinatorSubsystem::new(
parachains_db.clone(),
dispute_coordinator_config,
keystore.clone(),
Metrics::register(registry)?,
))
.dispute_distribution(DisputeDistributionSubsystem::new(
keystore,
dispute_req_receiver,
authority_discovery_service,
Metrics::register(registry)?,
))
.chain_selection(ChainSelectionSubsystem::new(chain_selection_config, parachains_db))
.leaves(Vec::from_iter(
leaves
.into_iter()
.map(|BlockInfo { hash, parent_hash: _, number }| (hash, number)),
))
.activation_external_listeners(Default::default())
.span_per_active_leaf(Default::default())
.active_leaves(Default::default())
.supports_parachains(runtime_client)
.known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE))
.metrics(metrics)
.spawner(spawner);
Ok(builder)
}
/// Trait for the `fn` generating the overseer.
///
/// Default behavior is to create an unmodified overseer, as `RealOverseerGen`
/// would do.
pub trait OverseerGen {
/// Overwrite the full generation of the overseer, including the subsystems.
fn generate<Spawner, RuntimeClient>(
&self,
connector: OverseerConnector,
args: OverseerGenArgs<'_, Spawner, RuntimeClient>,
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
let gen = RealOverseerGen;
RealOverseerGen::generate::<Spawner, RuntimeClient>(&gen, connector, args)
}
// It would be nice to make `create_subsystems` part of this trait,
// but the amount of generic arguments that would be required as
// as consequence make this rather annoying to implement and use.
}
use polkadot_overseer::KNOWN_LEAVES_CACHE_SIZE;
/// The regular set of subsystems.
pub struct RealOverseerGen;
impl OverseerGen for RealOverseerGen {
fn generate<Spawner, RuntimeClient>(
&self,
connector: OverseerConnector,
args: OverseerGenArgs<'_, Spawner, RuntimeClient>,
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
prepared_overseer_builder(args)?
.build_with_connector(connector)
.map_err(|e| e.into())
}
}
@@ -1,104 +0,0 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common 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.
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! This is almost 1:1 copy of `node/service/parachains_db/mod.rs` file from Polkadot repository.
//! The only exception is that we don't support db upgrades => no `upgrade.rs` module.
use kvdb::KeyValueDB;
use std::{io, path::PathBuf, sync::Arc};
mod columns {
pub const NUM_COLUMNS: u32 = 5;
pub const COL_AVAILABILITY_DATA: u32 = 0;
pub const COL_AVAILABILITY_META: u32 = 1;
pub const COL_APPROVAL_DATA: u32 = 2;
pub const COL_CHAIN_SELECTION_DATA: u32 = 3;
pub const COL_DISPUTE_COORDINATOR_DATA: u32 = 4;
}
/// Columns used by different subsystems.
#[derive(Debug, Clone)]
pub struct ColumnsConfig {
/// The column used by the av-store for data.
pub col_availability_data: u32,
/// The column used by the av-store for meta information.
pub col_availability_meta: u32,
/// The column used by approval voting for data.
pub col_approval_data: u32,
/// The column used by chain selection for data.
pub col_chain_selection_data: u32,
/// The column used by dispute coordinator for data.
pub col_dispute_coordinator_data: u32,
}
/// The real columns used by the parachains DB.
pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig {
col_availability_data: columns::COL_AVAILABILITY_DATA,
col_availability_meta: columns::COL_AVAILABILITY_META,
col_approval_data: columns::COL_APPROVAL_DATA,
col_chain_selection_data: columns::COL_CHAIN_SELECTION_DATA,
col_dispute_coordinator_data: columns::COL_DISPUTE_COORDINATOR_DATA,
};
/// The cache size for each column, in megabytes.
#[derive(Debug, Clone)]
pub struct CacheSizes {
/// Cache used by availability data.
pub availability_data: usize,
/// Cache used by availability meta.
pub availability_meta: usize,
/// Cache used by approval data.
pub approval_data: usize,
}
impl Default for CacheSizes {
fn default() -> Self {
CacheSizes { availability_data: 25, availability_meta: 1, approval_data: 5 }
}
}
fn other_io_error(err: String) -> io::Error {
io::Error::new(io::ErrorKind::Other, err)
}
/// Open the database on disk, creating it if it doesn't exist.
pub fn open_creating(root: PathBuf, cache_sizes: CacheSizes) -> io::Result<Arc<dyn KeyValueDB>> {
use kvdb_rocksdb::{Database, DatabaseConfig};
let path = root.join("parachains").join("db");
let mut db_config = DatabaseConfig::with_columns(columns::NUM_COLUMNS);
let _ = db_config
.memory_budget
.insert(columns::COL_AVAILABILITY_DATA, cache_sizes.availability_data);
let _ = db_config
.memory_budget
.insert(columns::COL_AVAILABILITY_META, cache_sizes.availability_meta);
let _ = db_config
.memory_budget
.insert(columns::COL_APPROVAL_DATA, cache_sizes.approval_data);
let path_str = path
.to_str()
.ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?;
std::fs::create_dir_all(&path_str)?;
let db = Database::open(&db_config, path_str)?;
Ok(Arc::new(db))
}
-756
View File
@@ -1,756 +0,0 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common 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.
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Rialto chain node service.
//!
//! The code is mostly copy of `service/src/lib.rs` file from Polkadot repository
//! without optional functions, and with BEEFY added on top.
use crate::overseer::{OverseerGen, OverseerGenArgs};
use polkadot_client::RuntimeApiCollection;
use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
use polkadot_node_core_av_store::Config as AvailabilityConfig;
use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig;
use polkadot_node_core_chain_selection::Config as ChainSelectionConfig;
use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
use polkadot_node_network_protocol::request_response::IncomingRequest;
use polkadot_overseer::{BlockInfo, OverseerConnector};
use polkadot_primitives::v1::BlockId;
use rialto_runtime::{self, opaque::Block, RuntimeApi};
use sc_client_api::ExecutorProvider;
use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch};
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
use sc_service::{config::PrometheusConfig, Configuration, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sp_api::{ConstructRuntimeApi, HeaderT};
use sp_consensus::SelectChain;
use sp_runtime::traits::Block as BlockT;
use std::{sync::Arc, time::Duration};
use substrate_prometheus_endpoint::Registry;
pub use polkadot_overseer::Handle;
pub use polkadot_primitives::v1::ParachainHost;
pub use sc_client_api::AuxStore;
pub use sp_authority_discovery::AuthorityDiscoveryApi;
pub use sp_blockchain::HeaderBackend;
pub use sp_consensus_babe::BabeApi;
pub type Executor = NativeElseWasmExecutor<ExecutorDispatch>;
// Our native executor instance.
pub struct ExecutorDispatch;
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
rialto_runtime::api::dispatch(method, data)
}
fn native_version() -> sc_executor::NativeVersion {
rialto_runtime::native_version()
}
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Cli(#[from] sc_cli::Error),
#[error(transparent)]
Blockchain(#[from] sp_blockchain::Error),
#[error(transparent)]
Consensus(#[from] sp_consensus::Error),
#[error(transparent)]
Service(#[from] sc_service::Error),
#[error(transparent)]
Telemetry(#[from] sc_telemetry::Error),
#[error("Failed to create an overseer")]
Overseer(#[from] polkadot_overseer::SubsystemError),
#[error(transparent)]
Prometheus(#[from] substrate_prometheus_endpoint::PrometheusError),
#[error("Authorities require the real overseer implementation")]
AuthoritiesRequireRealOverseer,
#[error("Creating a custom database is required for validators")]
DatabasePathRequired,
}
type FullClient = sc_service::TFullClient<Block, RuntimeApi, Executor>;
type FullBackend = sc_service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
type FullGrandpaBlockImport =
sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>;
type FullTransactionPool = sc_transaction_pool::FullPool<Block, FullClient>;
type FullBabeBlockImport =
sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>;
type FullBabeLink = sc_consensus_babe::BabeLink<Block>;
type FullGrandpaLink = sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>;
// If we're using prometheus, use a registry with a prefix of `polkadot`.
fn set_prometheus_registry(config: &mut Configuration) -> Result<(), Error> {
if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
}
Ok(())
}
// Needed here for complex return type while `impl Trait` in type aliases is unstable.
#[allow(clippy::type_complexity)]
pub fn new_partial(
config: &mut Configuration,
) -> Result<
sc_service::PartialComponents<
FullClient,
FullBackend,
FullSelectChain,
sc_consensus::DefaultImportQueue<Block, FullClient>,
FullTransactionPool,
(
impl Fn(
sc_rpc::DenyUnsafe,
sc_rpc::SubscriptionTaskExecutor,
) -> Result<jsonrpc_core::IoHandler<sc_service::RpcMetadata>, sc_service::Error>,
(
FullBabeBlockImport,
FullGrandpaLink,
FullBabeLink,
beefy_gadget::notification::BeefySignedCommitmentSender<Block>,
),
sc_finality_grandpa::SharedVoterState,
std::time::Duration,
Option<Telemetry>,
),
>,
Error,
>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient> + Send + Sync + 'static,
<RuntimeApi as ConstructRuntimeApi<Block, FullClient>>::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
set_prometheus_registry(config)?;
let telemetry = config
.telemetry_endpoints
.clone()
.filter(|x| !x.is_empty())
.map(|endpoints| -> Result<_, sc_telemetry::Error> {
let worker = TelemetryWorker::new(16)?;
let telemetry = worker.handle().new_telemetry(endpoints);
Ok((worker, telemetry))
})
.transpose()?;
let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(
config.wasm_method,
config.default_heap_pages,
config.max_runtime_instances,
);
let (client, backend, keystore_container, task_manager) =
sc_service::new_full_parts::<Block, RuntimeApi, Executor>(
config,
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
executor,
)?;
let client = Arc::new(client);
let telemetry = telemetry.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", None, worker.run());
telemetry
});
let select_chain = sc_consensus::LongestChain::new(backend.clone());
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
config.transaction_pool.clone(),
config.role.is_authority().into(),
config.prometheus_registry(),
task_manager.spawn_essential_handle(),
client.clone(),
);
let (grandpa_block_import, grandpa_link) =
sc_finality_grandpa::block_import_with_authority_set_hard_forks(
client.clone(),
&(client.clone() as Arc<_>),
select_chain.clone(),
Vec::new(),
telemetry.as_ref().map(|x| x.handle()),
)?;
let justification_import = grandpa_block_import.clone();
let babe_config = sc_consensus_babe::Config::get_or_compute(&*client)?;
let (block_import, babe_link) =
sc_consensus_babe::block_import(babe_config.clone(), grandpa_block_import, client.clone())?;
let slot_duration = babe_link.config().slot_duration();
let import_queue = sc_consensus_babe::import_queue(
babe_link.clone(),
block_import.clone(),
Some(Box::new(justification_import)),
client.clone(),
select_chain.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(),
config.prometheus_registry(),
sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
telemetry.as_ref().map(|x| x.handle()),
)?;
let justification_stream = grandpa_link.justification_stream();
let shared_authority_set = grandpa_link.shared_authority_set().clone();
let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
let (signed_commitment_sender, signed_commitment_stream) =
beefy_gadget::notification::BeefySignedCommitmentStream::channel();
let import_setup = (block_import, grandpa_link, babe_link, signed_commitment_sender);
let rpc_setup = shared_voter_state.clone();
let slot_duration = babe_config.slot_duration();
let rpc_extensions_builder = {
let client = client.clone();
let transaction_pool = transaction_pool.clone();
let backend = backend.clone();
move |deny_unsafe,
subscription_executor: sc_rpc::SubscriptionTaskExecutor|
-> Result<jsonrpc_core::IoHandler<sc_service::RpcMetadata>, sc_service::Error> {
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler};
use substrate_frame_rpc_system::{FullSystem, SystemApi};
let backend = backend.clone();
let client = client.clone();
let pool = transaction_pool.clone();
let shared_voter_state = shared_voter_state.clone();
let finality_proof_provider = GrandpaFinalityProofProvider::new_for_service(
backend,
Some(shared_authority_set.clone()),
);
let mut io = jsonrpc_core::IoHandler::default();
io.extend_with(SystemApi::to_delegate(FullSystem::new(
client.clone(),
pool,
deny_unsafe,
)));
io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
client.clone(),
)));
io.extend_with(GrandpaApi::to_delegate(GrandpaRpcHandler::new(
shared_authority_set.clone(),
shared_voter_state,
justification_stream.clone(),
subscription_executor.clone(),
finality_proof_provider,
)));
io.extend_with(beefy_gadget_rpc::BeefyApi::to_delegate(
beefy_gadget_rpc::BeefyRpcHandler::new(
signed_commitment_stream.clone(),
subscription_executor,
),
));
io.extend_with(pallet_mmr_rpc::MmrApi::to_delegate(pallet_mmr_rpc::Mmr::new(client)));
Ok(io)
}
};
Ok(sc_service::PartialComponents {
client,
backend,
task_manager,
keystore_container,
select_chain,
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry),
})
}
pub struct NewFull<C> {
pub task_manager: TaskManager,
pub client: C,
pub overseer_handle: Option<Handle>,
pub network: Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
pub rpc_handlers: sc_service::RpcHandlers,
pub backend: Arc<FullBackend>,
}
/// The maximum number of active leaves we forward to the [`Overseer`] on start up.
const MAX_ACTIVE_LEAVES: usize = 4;
/// Returns the active leaves the overseer should start with.
async fn active_leaves(
select_chain: &sc_consensus::LongestChain<FullBackend, Block>,
client: &FullClient,
) -> Result<Vec<BlockInfo>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient> + Send + Sync + 'static,
<RuntimeApi as ConstructRuntimeApi<Block, FullClient>>::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
let best_block = select_chain.best_chain().await?;
let mut leaves = select_chain
.leaves()
.await
.unwrap_or_default()
.into_iter()
.filter_map(|hash| {
let number = client.number(hash).ok()??;
// Only consider leaves that are in maximum an uncle of the best block.
if number < best_block.number().saturating_sub(1) || hash == best_block.hash() {
return None
}
let parent_hash = client.header(&BlockId::Hash(hash)).ok()??.parent_hash;
Some(BlockInfo { hash, parent_hash, number })
})
.collect::<Vec<_>>();
// Sort by block number and get the maximum number of leaves
leaves.sort_by_key(|b| b.number);
leaves.push(BlockInfo {
hash: best_block.hash(),
parent_hash: *best_block.parent_hash(),
number: *best_block.number(),
});
Ok(leaves.into_iter().rev().take(MAX_ACTIVE_LEAVES).collect())
}
// Create a new full node.
pub fn new_full(
mut config: Configuration,
program_path: Option<std::path::PathBuf>,
overseer_gen: impl OverseerGen,
) -> Result<NewFull<Arc<FullClient>>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient> + Send + Sync + 'static,
<RuntimeApi as ConstructRuntimeApi<Block, FullClient>>::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
let is_collator = false;
let role = config.role.clone();
let force_authoring = config.force_authoring;
let backoff_authoring_blocks =
Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default());
let disable_grandpa = config.disable_grandpa;
let name = config.network.node_name.clone();
let sc_service::PartialComponents {
client,
backend,
mut task_manager,
keystore_container,
select_chain,
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
} = new_partial(&mut config)?;
let prometheus_registry = config.prometheus_registry().cloned();
let overseer_connector = OverseerConnector::default();
let shared_voter_state = rpc_setup;
let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
// Note: GrandPa is pushed before the Polkadot-specific protocols. This doesn't change
// anything in terms of behaviour, but makes the logs more consistent with the other
// Substrate nodes.
config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
config.network.extra_sets.push(beefy_gadget::beefy_peers_set_config());
{
use polkadot_network_bridge::{peer_sets_info, IsAuthority};
let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No };
config.network.extra_sets.extend(peer_sets_info(is_authority));
}
let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let (collation_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let (available_data_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver();
config.network.request_response_protocols.push(cfg);
let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new(
backend.clone(),
import_setup.1.shared_authority_set().clone(),
vec![],
));
let (network, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
transaction_pool: transaction_pool.clone(),
spawn_handle: task_manager.spawn_handle(),
import_queue,
block_announce_validator_builder: None,
warp_sync: Some(warp_sync),
})?;
if config.offchain_worker.enabled {
let _ = sc_service::build_offchain_workers(
&config,
task_manager.spawn_handle(),
client.clone(),
network.clone(),
);
}
let parachains_db = crate::parachains_db::open_creating(
config.database.path().ok_or(Error::DatabasePathRequired)?.into(),
crate::parachains_db::CacheSizes::default(),
)?;
let availability_config = AvailabilityConfig {
col_data: crate::parachains_db::REAL_COLUMNS.col_availability_data,
col_meta: crate::parachains_db::REAL_COLUMNS.col_availability_meta,
};
let approval_voting_config = ApprovalVotingConfig {
col_data: crate::parachains_db::REAL_COLUMNS.col_approval_data,
slot_duration_millis: slot_duration.as_millis() as u64,
};
let candidate_validation_config = CandidateValidationConfig {
artifacts_cache_path: config
.database
.path()
.ok_or(Error::DatabasePathRequired)?
.join("pvf-artifacts"),
program_path: match program_path {
None => std::env::current_exe()?,
Some(p) => p,
},
};
let chain_selection_config = ChainSelectionConfig {
col_data: crate::parachains_db::REAL_COLUMNS.col_chain_selection_data,
stagnant_check_interval: polkadot_node_core_chain_selection::StagnantCheckInterval::never(),
};
let dispute_coordinator_config = DisputeCoordinatorConfig {
col_data: crate::parachains_db::REAL_COLUMNS.col_dispute_coordinator_data,
};
let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
config,
backend: backend.clone(),
client: client.clone(),
keystore: keystore_container.sync_keystore(),
network: network.clone(),
rpc_extensions_builder: Box::new(rpc_extensions_builder),
transaction_pool: transaction_pool.clone(),
task_manager: &mut task_manager,
system_rpc_tx,
telemetry: telemetry.as_mut(),
})?;
let (block_import, link_half, babe_link, signed_commitment_sender) = import_setup;
let overseer_client = client.clone();
let spawner = task_manager.spawn_handle();
let active_leaves = futures::executor::block_on(active_leaves(&select_chain, &*client))?;
let authority_discovery_service = if role.is_authority() || is_collator {
use futures::StreamExt;
use sc_network::Event;
let authority_discovery_role = if role.is_authority() {
sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore())
} else {
// don't publish our addresses when we're only a collator
sc_authority_discovery::Role::Discover
};
let dht_event_stream =
network.event_stream("authority-discovery").filter_map(|e| async move {
match e {
Event::Dht(e) => Some(e),
_ => None,
}
});
let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config(
sc_authority_discovery::WorkerConfig {
publish_non_global_ips: auth_disc_publish_non_global_ips,
..Default::default()
},
client.clone(),
network.clone(),
Box::pin(dht_event_stream),
authority_discovery_role,
prometheus_registry.clone(),
);
task_manager
.spawn_handle()
.spawn("authority-discovery-worker", None, worker.run());
Some(service)
} else {
None
};
// we'd say let overseer_handler =
// authority_discovery_service.map(|authority_discovery_service|, ...), but in that case we
// couldn't use ? to propagate errors
let local_keystore = keystore_container.local_keystore();
let maybe_params =
local_keystore.and_then(move |k| authority_discovery_service.map(|a| (a, k)));
let overseer_handle = if let Some((authority_discovery_service, keystore)) = maybe_params {
let (overseer, overseer_handle) = overseer_gen
.generate::<sc_service::SpawnTaskHandle, FullClient>(
overseer_connector,
OverseerGenArgs {
leaves: active_leaves,
keystore,
runtime_client: overseer_client.clone(),
parachains_db,
availability_config,
approval_voting_config,
network_service: network.clone(),
authority_discovery_service,
registry: prometheus_registry.as_ref(),
spawner,
candidate_validation_config,
available_data_req_receiver,
chain_selection_config,
chunk_req_receiver,
collation_req_receiver,
dispute_coordinator_config,
dispute_req_receiver,
pov_req_receiver,
statement_req_receiver,
},
)?;
let handle = Handle::new(overseer_handle);
{
let handle = handle.clone();
task_manager.spawn_essential_handle().spawn_blocking(
"overseer",
None,
Box::pin(async move {
use futures::{pin_mut, select, FutureExt};
let forward = polkadot_overseer::forward_events(overseer_client, handle);
let forward = forward.fuse();
let overseer_fut = overseer.run().fuse();
pin_mut!(overseer_fut);
pin_mut!(forward);
select! {
_ = forward => (),
_ = overseer_fut => (),
complete => (),
}
}),
);
}
Some(handle)
} else {
None
};
if role.is_authority() {
let can_author_with =
sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
let proposer = sc_basic_authorship::ProposerFactory::new(
task_manager.spawn_handle(),
client.clone(),
transaction_pool,
prometheus_registry.as_ref(),
telemetry.as_ref().map(|x| x.handle()),
);
let client_clone = client.clone();
let overseer_handle =
overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone();
let slot_duration = babe_link.config().slot_duration();
let babe_config = sc_consensus_babe::BabeParams {
keystore: keystore_container.sync_keystore(),
client: client.clone(),
select_chain,
block_import,
env: proposer,
sync_oracle: network.clone(),
justification_sync_link: network.clone(),
create_inherent_data_providers: move |parent, ()| {
let client_clone = client_clone.clone();
let overseer_handle = overseer_handle.clone();
async move {
let parachain = polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::create(
&*client_clone,
overseer_handle,
parent,
)
.await
.map_err(Box::new)?;
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,
backoff_authoring_blocks,
babe_link,
can_author_with,
block_proposal_slot_portion: sc_consensus_babe::SlotProportion::new(2f32 / 3f32),
max_block_proposal_slot_portion: None,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
let babe = sc_consensus_babe::start_babe(babe_config)?;
task_manager.spawn_essential_handle().spawn_blocking("babe", None, babe);
}
// if the node isn't actively participating in consensus then it doesn't
// need a keystore, regardless of which protocol we use below.
let keystore_opt =
if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None };
let beefy_params = beefy_gadget::BeefyParams {
client: client.clone(),
backend: backend.clone(),
key_store: keystore_opt.clone(),
network: network.clone(),
signed_commitment_sender,
min_block_delta: 2,
prometheus_registry: prometheus_registry.clone(),
};
// Start the BEEFY bridge gadget.
task_manager.spawn_essential_handle().spawn_blocking(
"beefy-gadget",
None,
beefy_gadget::start_beefy_gadget::<_, _, _, _>(beefy_params),
);
let config = sc_finality_grandpa::Config {
// FIXME substrate#1578 make this available through chainspec
gossip_duration: Duration::from_millis(1000),
justification_period: 512,
name: Some(name),
observer_enabled: false,
keystore: keystore_opt,
local_role: role,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
let enable_grandpa = !disable_grandpa;
if enable_grandpa {
// start the full GRANDPA voter
// NOTE: unlike in substrate we are currently running the full
// GRANDPA voter protocol for all full nodes (regardless of whether
// they're validators or not). at this point the full voter should
// provide better guarantees of block and vote data availability than
// the observer.
// add a custom voting rule to temporarily stop voting for new blocks
// after the given pause block is finalized and restarting after the
// given delay.
let builder = sc_finality_grandpa::VotingRulesBuilder::default();
let voting_rule = builder.build();
let grandpa_config = sc_finality_grandpa::GrandpaParams {
config,
link: link_half,
network: network.clone(),
voting_rule,
prometheus_registry,
shared_voter_state,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
task_manager.spawn_essential_handle().spawn_blocking(
"grandpa-voter",
None,
sc_finality_grandpa::run_grandpa_voter(grandpa_config)?,
);
}
network_starter.start_network();
Ok(NewFull { task_manager, client, overseer_handle, network, rpc_handlers, backend })
}
pub fn build_full(
config: Configuration,
overseer_gen: impl OverseerGen,
) -> Result<NewFull<Arc<FullClient>>, Error> {
new_full(config, None, overseer_gen)
}