mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 15:37:56 +00:00
reuse polkadot-service code (#1273)
This commit is contained in:
committed by
Bastian Köcher
parent
1d99ad3619
commit
1ec2edd357
@@ -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" }
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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<()> {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user