mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 04:11:07 +00:00
Support both polkadot and kusama runtimes (#704)
* Allow both polkadot and kusama runtimes * Allow both polkadot and kusama runtimes * Make `collator` build * Removed kusama runtime * Introduced common runtime * Updated for latest substrate * Updated CI targets * Updated CI version check * Removed unused dependency * Pulled latests substrate * Pulled latest substrate * Fixed version * Apply suggestions from code review Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * NEW_HEADS_IDENTIFIER moved to primitives * Updated CI check script * Fixed script * Set epoch duration for polkadot * ci: check_runtime for both runtimes Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: gabriel klawitter <gabreal@users.noreply.github.com>
This commit is contained in:
committed by
Gavin Wood
parent
9a9bbd1c2d
commit
a00d74d825
@@ -41,12 +41,19 @@ impl Default for ChainSpec {
|
||||
/// Get a chain config from a spec setting.
|
||||
impl ChainSpec {
|
||||
pub(crate) fn load(self) -> Result<service::ChainSpec, String> {
|
||||
Ok(match self {
|
||||
ChainSpec::Kusama => service::chain_spec::kusama_config()?,
|
||||
ChainSpec::Development => service::chain_spec::development_config(),
|
||||
ChainSpec::LocalTestnet => service::chain_spec::local_testnet_config(),
|
||||
ChainSpec::StagingTestnet => service::chain_spec::staging_testnet_config(),
|
||||
})
|
||||
match self {
|
||||
ChainSpec::Development => Ok(service::chain_spec::development_config()),
|
||||
ChainSpec::LocalTestnet => Ok(service::chain_spec::local_testnet_config()),
|
||||
ChainSpec::StagingTestnet => Ok(service::chain_spec::staging_testnet_config()),
|
||||
ChainSpec::Kusama => service::chain_spec::kusama_config(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_kusama(&self) -> bool {
|
||||
match self {
|
||||
ChainSpec::Development | ChainSpec::LocalTestnet | ChainSpec::StagingTestnet => false,
|
||||
ChainSpec::Kusama => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from(s: &str) -> Option<Self> {
|
||||
|
||||
+113
-108
@@ -26,53 +26,27 @@ mod browser;
|
||||
use chain_spec::ChainSpec;
|
||||
use futures::{
|
||||
Future, FutureExt, TryFutureExt, future::select, channel::oneshot, compat::Future01CompatExt,
|
||||
task::Spawn
|
||||
};
|
||||
use tokio::runtime::Runtime;
|
||||
use log::{info, error};
|
||||
use log::info;
|
||||
use structopt::StructOpt;
|
||||
|
||||
pub use service::{
|
||||
AbstractService, CustomConfiguration,
|
||||
ProvideRuntimeApi, CoreApi, ParachainHost,
|
||||
AbstractService, CustomConfiguration, ProvideRuntimeApi, CoreApi, ParachainHost, IsKusama, self,
|
||||
WrappedExecutor
|
||||
};
|
||||
|
||||
pub use cli::{VersionInfo, IntoExit, NoCustom};
|
||||
pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams};
|
||||
pub use cli::{display_role, error};
|
||||
|
||||
fn load_spec(id: &str) -> Result<Option<service::ChainSpec>, String> {
|
||||
/// Load the `ChainSpec` for the given `id`.
|
||||
pub fn load_spec(id: &str) -> Result<Option<service::ChainSpec>, String> {
|
||||
Ok(match ChainSpec::from(id) {
|
||||
Some(spec) => Some(spec.load()?),
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Additional worker making use of the node, to run asynchronously before shutdown.
|
||||
///
|
||||
/// This will be invoked with the service and spawn a future that resolves
|
||||
/// when complete.
|
||||
pub trait Worker: IntoExit {
|
||||
/// A future that resolves when the work is done or the node should exit.
|
||||
/// This will be run on a tokio runtime.
|
||||
type Work: Future<Output=()> + Unpin + Send + 'static;
|
||||
|
||||
/// Return configuration for the polkadot node.
|
||||
// TODO: make this the full configuration, so embedded nodes don't need
|
||||
// string CLI args (https://github.com/paritytech/polkadot/issues/111)
|
||||
fn configuration(&self) -> service::CustomConfiguration { Default::default() }
|
||||
|
||||
/// Do work and schedule exit.
|
||||
fn work<S, SC, B, CE, SP>(self, service: &S, spawner: SP) -> Self::Work
|
||||
where S: AbstractService<Block = service::Block, RuntimeApi = service::RuntimeApi,
|
||||
Backend = B, SelectChain = SC,
|
||||
NetworkSpecialization = service::PolkadotProtocol, CallExecutor = CE>,
|
||||
SC: service::SelectChain<service::Block> + 'static,
|
||||
B: service::Backend<service::Block, service::Blake2Hasher> + 'static,
|
||||
CE: service::CallExecutor<service::Block, service::Blake2Hasher> + Clone + Send + Sync + 'static,
|
||||
SP: Spawn + Clone + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt, Clone)]
|
||||
enum PolkadotSubCommands {
|
||||
#[structopt(name = "validation-worker", setting = structopt::clap::AppSettings::Hidden)]
|
||||
@@ -96,81 +70,111 @@ struct PolkadotSubParams {
|
||||
}
|
||||
|
||||
/// Parses polkadot specific CLI arguments and run the service.
|
||||
pub fn run<W>(worker: W, version: cli::VersionInfo) -> error::Result<()> where
|
||||
W: Worker,
|
||||
{
|
||||
match cli::parse_and_prepare::<PolkadotSubCommands, PolkadotSubParams, _>(
|
||||
pub fn run<E: IntoExit>(exit: E, version: cli::VersionInfo) -> error::Result<()> {
|
||||
let cmd = cli::parse_and_prepare::<PolkadotSubCommands, PolkadotSubParams, _>(
|
||||
&version,
|
||||
"parity-polkadot",
|
||||
std::env::args(),
|
||||
) {
|
||||
cli::ParseAndPrepare::Run(cmd) => cmd.run(load_spec, worker,
|
||||
|worker, _cli_args, custom_args, mut config| {
|
||||
info!("{}", version.name);
|
||||
info!(" version {}", config.full_version());
|
||||
info!(" by {}, 2017-2019", version.author);
|
||||
info!("Chain specification: {}", config.chain_spec.name());
|
||||
if config.chain_spec.name().starts_with("Kusama") {
|
||||
info!("----------------------------");
|
||||
info!("This chain is not in any way");
|
||||
info!(" endorsed by the ");
|
||||
info!(" KUSAMA FOUNDATION ");
|
||||
info!("----------------------------");
|
||||
}
|
||||
info!("Node name: {}", config.name);
|
||||
info!("Roles: {}", display_role(&config));
|
||||
config.custom = worker.configuration();
|
||||
config.custom.authority_discovery_enabled = custom_args.authority_discovery_enabled;
|
||||
let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?;
|
||||
match config.roles {
|
||||
service::Roles::LIGHT =>
|
||||
run_until_exit(
|
||||
runtime,
|
||||
service::new_light(config).map_err(|e| format!("{:?}", e))?,
|
||||
worker
|
||||
),
|
||||
_ => run_until_exit(
|
||||
runtime,
|
||||
service::new_full(config).map_err(|e| format!("{:?}", e))?,
|
||||
worker
|
||||
),
|
||||
}.map_err(|e| format!("{:?}", e))
|
||||
}),
|
||||
cli::ParseAndPrepare::BuildSpec(cmd) => cmd.run::<NoCustom, _, _, _>(load_spec),
|
||||
cli::ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops(config)?), load_spec, worker),
|
||||
cli::ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops(config)?), load_spec, worker),
|
||||
cli::ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder::<(), _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops(config)?), load_spec, worker),
|
||||
cli::ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),
|
||||
cli::ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops(config)?), load_spec),
|
||||
cli::ParseAndPrepare::CustomCommand(PolkadotSubCommands::ValidationWorker(args)) => {
|
||||
if cfg!(feature = "browser") {
|
||||
Err(error::Error::Input("Cannot run validation worker in browser".into()))
|
||||
} else {
|
||||
#[cfg(not(feature = "browser"))]
|
||||
service::run_validation_worker(&args.mem_id)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
||||
if cmd
|
||||
.shared_params()
|
||||
.and_then(|p| p.chain.as_ref())
|
||||
.and_then(|c| ChainSpec::from(c))
|
||||
.map_or(false, |c| c.is_kusama())
|
||||
{
|
||||
execute_cmd_with_runtime::<
|
||||
service::kusama_runtime::RuntimeApi,
|
||||
service::KusamaExecutor,
|
||||
service::kusama_runtime::UncheckedExtrinsic,
|
||||
_
|
||||
>(exit, &version, cmd)
|
||||
} else {
|
||||
execute_cmd_with_runtime::<
|
||||
service::polkadot_runtime::RuntimeApi,
|
||||
service::PolkadotExecutor,
|
||||
service::polkadot_runtime::UncheckedExtrinsic,
|
||||
_
|
||||
>(exit, &version, cmd)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_until_exit<T, SC, B, CE, W>(
|
||||
mut runtime: Runtime,
|
||||
service: T,
|
||||
worker: W,
|
||||
/// Execute the given `cmd` with the given runtime.
|
||||
fn execute_cmd_with_runtime<R, D, E, X>(
|
||||
exit: X,
|
||||
version: &cli::VersionInfo,
|
||||
cmd: cli::ParseAndPrepare<PolkadotSubCommands, PolkadotSubParams>,
|
||||
) -> error::Result<()>
|
||||
where
|
||||
T: AbstractService<Block = service::Block, RuntimeApi = service::RuntimeApi,
|
||||
SelectChain = SC, Backend = B, NetworkSpecialization = service::PolkadotProtocol, CallExecutor = CE>,
|
||||
SC: service::SelectChain<service::Block> + 'static,
|
||||
B: service::Backend<service::Block, service::Blake2Hasher> + 'static,
|
||||
CE: service::CallExecutor<service::Block, service::Blake2Hasher> + Clone + Send + Sync + 'static,
|
||||
W: Worker,
|
||||
where
|
||||
R: service::ConstructRuntimeApi<service::Block, service::TFullClient<service::Block, R, D>>
|
||||
+ service::ConstructRuntimeApi<service::Block, service::TLightClient<service::Block, R, D>>
|
||||
+ Send + Sync + 'static,
|
||||
<R as service::ConstructRuntimeApi<service::Block, service::TFullClient<service::Block, R, D>>>::RuntimeApi: service::RuntimeApiCollection<E>,
|
||||
<R as service::ConstructRuntimeApi<service::Block, service::TLightClient<service::Block, R, D>>>::RuntimeApi: service::RuntimeApiCollection<E>,
|
||||
E: service::Codec + Send + Sync + 'static,
|
||||
D: service::NativeExecutionDispatch + 'static,
|
||||
X: IntoExit,
|
||||
{
|
||||
match cmd {
|
||||
cli::ParseAndPrepare::Run(cmd) => cmd.run(&load_spec, exit,
|
||||
|exit, _cli_args, custom_args, mut config| {
|
||||
info!("{}", version.name);
|
||||
info!(" version {}", config.full_version());
|
||||
info!(" by {}, 2017-2019", version.author);
|
||||
info!("Chain specification: {}", config.chain_spec.name());
|
||||
if config.is_kusama() {
|
||||
info!("----------------------------");
|
||||
info!("This chain is not in any way");
|
||||
info!(" endorsed by the ");
|
||||
info!(" KUSAMA FOUNDATION ");
|
||||
info!("----------------------------");
|
||||
}
|
||||
info!("Node name: {}", config.name);
|
||||
info!("Roles: {}", display_role(&config));
|
||||
config.custom = service::CustomConfiguration::default();
|
||||
config.custom.authority_discovery_enabled = custom_args.authority_discovery_enabled;
|
||||
let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?;
|
||||
match config.roles {
|
||||
service::Roles::LIGHT =>
|
||||
run_until_exit(
|
||||
runtime,
|
||||
service::new_light::<R, D, E>(config).map_err(|e| format!("{:?}", e))?,
|
||||
exit.into_exit(),
|
||||
),
|
||||
_ => run_until_exit(
|
||||
runtime,
|
||||
service::new_full::<R, D, E>(config).map_err(|e| format!("{:?}", e))?,
|
||||
exit.into_exit(),
|
||||
),
|
||||
}.map_err(|e| format!("{:?}", e))
|
||||
}),
|
||||
cli::ParseAndPrepare::BuildSpec(cmd) => cmd.run::<NoCustom, _, _, _>(&load_spec),
|
||||
cli::ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops::<R, D, E>(config)?), &load_spec, exit),
|
||||
cli::ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops::<R, D, E>(config)?), &load_spec, exit),
|
||||
cli::ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops::<R, D, E>(config)?), &load_spec, exit),
|
||||
cli::ParseAndPrepare::PurgeChain(cmd) => cmd.run(&load_spec),
|
||||
cli::ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<_, _, _, _, _, _>(|config|
|
||||
Ok(service::new_chain_ops::<R, D, E>(config)?), &load_spec),
|
||||
cli::ParseAndPrepare::CustomCommand(PolkadotSubCommands::ValidationWorker(args)) => {
|
||||
if cfg!(feature = "browser") {
|
||||
Err(error::Error::Input("Cannot run validation worker in browser".into()))
|
||||
} else {
|
||||
#[cfg(not(feature = "browser"))]
|
||||
service::run_validation_worker(&args.mem_id)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the given `service` using the `runtime` until it exits or `e` fires.
|
||||
pub fn run_until_exit(
|
||||
mut runtime: Runtime,
|
||||
service: impl AbstractService,
|
||||
e: impl Future<Output = ()> + Send + Unpin + 'static,
|
||||
) -> error::Result<()> {
|
||||
let (exit_send, exit) = oneshot::channel();
|
||||
|
||||
let executor = runtime.executor();
|
||||
@@ -185,20 +189,21 @@ fn run_until_exit<T, SC, B, CE, W>(
|
||||
// but we need to keep holding a reference to the global telemetry guard
|
||||
let _telemetry = service.telemetry();
|
||||
|
||||
let work = worker.work(&service, WrappedExecutor(executor));
|
||||
let service = service
|
||||
.map_err(|err| error!("Error while running Service: {}", err))
|
||||
.compat();
|
||||
let future = select(service, work)
|
||||
.map(|_| Ok::<_, ()>(()))
|
||||
.compat();
|
||||
let _ = runtime.block_on(future);
|
||||
let service_res = {
|
||||
let service = service
|
||||
.map_err(|err| error::Error::Service(err))
|
||||
.compat();
|
||||
let select = select(service, e)
|
||||
.map(|_| Ok(()))
|
||||
.compat();
|
||||
runtime.block_on(select)
|
||||
};
|
||||
|
||||
let _ = exit_send.send(());
|
||||
|
||||
use futures01::Future;
|
||||
|
||||
// TODO [andre]: timeout this future substrate/#1318
|
||||
let _ = runtime.shutdown_on_idle().wait();
|
||||
|
||||
Ok(())
|
||||
service_res
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user