ChainSpec extensions (#3692)

* Add some chainspec tests and make sure we validate it.

* Manual implementation of Extension + Forks definitions.

* Move chain spec to separate crate.

* Allow using ChainSpec with extensions.

* Renames.

* Implement Extension derive.

* Implement Extension for Forks.

* Support specifying fork blocks.

* make for_blocks work

* Support forks correctly.

* Add a bunch of docs.

* Make fork blocks optional.

* Add missing docs.

* Fix build.

* Use struct for check_block params.

* Fix tests?

* Clean up.
This commit is contained in:
Tomasz Drwięga
2019-09-28 19:05:36 +02:00
committed by Gavin Wood
parent c555b9bf88
commit 667ee95f5d
39 changed files with 1368 additions and 336 deletions
+43 -9
View File
@@ -16,15 +16,16 @@
//! Substrate chain configurations.
use chain_spec::ChainSpecExtension;
use primitives::{Pair, Public, crypto::UncheckedInto};
pub use node_primitives::{AccountId, Balance};
use serde::{Serialize, Deserialize};
use node_runtime::{
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus,
StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
};
use node_runtime::Block;
use node_runtime::constants::{time::*, currency::*};
pub use node_runtime::GenesisConfig;
use substrate_service;
use hex_literal::hex;
use substrate_telemetry::TelemetryEndpoints;
@@ -33,11 +34,26 @@ use babe_primitives::{AuthorityId as BabeId};
use im_online::sr25519::{AuthorityId as ImOnlineId};
use sr_primitives::Perbill;
pub use node_primitives::{AccountId, Balance};
pub use node_runtime::GenesisConfig;
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
/// Specialized `ChainSpec`.
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
/// Node `ChainSpec` extensions.
///
/// Additional parameters for some Substrate core modules,
/// customizable from the chain spec.
#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)]
pub struct Extensions {
/// Block numbers with known hashes.
pub fork_blocks: client::ForkBlocks<Block>,
}
/// Specialized `ChainSpec`.
pub type ChainSpec = substrate_service::ChainSpec<
GenesisConfig,
Extensions,
>;
/// Flaming Fir testnet generator
pub fn flaming_fir_config() -> Result<ChainSpec, String> {
ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..])
@@ -191,7 +207,7 @@ pub fn staging_testnet_config() -> ChainSpec {
Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])),
None,
None,
None,
Default::default(),
)
}
@@ -327,7 +343,16 @@ fn development_config_genesis() -> GenesisConfig {
/// Development config (single validator Alice)
pub fn development_config() -> ChainSpec {
ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None)
ChainSpec::from_genesis(
"Development",
"dev",
development_config_genesis,
vec![],
None,
None,
None,
Default::default(),
)
}
fn local_testnet_genesis() -> GenesisConfig {
@@ -344,7 +369,16 @@ fn local_testnet_genesis() -> GenesisConfig {
/// Local testnet config (multivalidator Alice + Bob)
pub fn local_testnet_config() -> ChainSpec {
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None)
ChainSpec::from_genesis(
"Local Testnet",
"local_testnet",
local_testnet_genesis,
vec![],
None,
None,
None,
Default::default(),
)
}
#[cfg(test)]
@@ -375,7 +409,7 @@ pub(crate) mod tests {
None,
None,
None,
None,
Default::default(),
)
}
@@ -389,7 +423,7 @@ pub(crate) mod tests {
None,
None,
None,
None,
Default::default(),
)
}
+9 -7
View File
@@ -28,7 +28,7 @@ mod factory_impl;
use tokio::prelude::Future;
use tokio::runtime::{Builder as RuntimeBuilder, Runtime};
pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam};
use substrate_service::{AbstractService, Roles as ServiceRoles};
use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration};
use log::info;
use structopt::{StructOpt, clap::App};
use cli::{AugmentClap, GetLogFilter, parse_and_prepare, ParseAndPrepare};
@@ -158,9 +158,11 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
{
type Config<A, B> = Configuration<(), A, B>;
match parse_and_prepare::<CustomSubcommands, NoCustom, _>(&version, "substrate-node", args) {
ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit,
|exit, _cli_args, _custom_args, config| {
ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit,
|exit, _cli_args, _custom_args, config: Config<_, _>| {
info!("{}", version.name);
info!(" version {}", config.full_version());
info!(" by Parity Technologies, 2017-2019");
@@ -183,15 +185,15 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
}.map_err(|e| format!("{:?}", e))
}),
ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec),
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config|
ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec, exit),
ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<(), _, _, _, _>(|config|
ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_, _>|
Ok(new_full_start!(config).0), load_spec),
ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => {
let mut config = cli::create_config_with_db_path::<(), _, _>(
let mut config: Config<_, _> = cli::create_config_with_db_path(
load_spec,
&cli_args.shared_params,
&version,
+5 -2
View File
@@ -239,8 +239,11 @@ type ConcreteClient =
#[allow(dead_code)]
type ConcreteBackend = Backend<ConcreteBlock>;
/// A specialized configuration object for setting up the node..
pub type NodeConfiguration<C> = Configuration<C, GenesisConfig, crate::chain_spec::Extensions>;
/// Builds a new service for a full client.
pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)
pub fn new_full<C: Send + Default + 'static>(config: NodeConfiguration<C>)
-> Result<
NewService<
ConcreteBlock,
@@ -262,7 +265,7 @@ pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisCon
}
/// Builds a new service for a light client.
pub fn new_light<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)
pub fn new_light<C: Send + Default + 'static>(config: NodeConfiguration<C>)
-> Result<impl AbstractService, ServiceError> {
type RpcExtension = jsonrpc_core::IoHandler<substrate_rpc::Metadata>;
let inherent_data_providers = InherentDataProviders::new();