ChainSpec trait (#5185)

* ChainSpec trait

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Added docs

* Fixed build

* Fixed build

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Arkadiy Paronyan
2020-03-12 00:00:10 +01:00
committed by GitHub
parent d2345e8d5c
commit dc0bf210fb
38 changed files with 354 additions and 335 deletions
+29 -50
View File
@@ -26,7 +26,7 @@ use sc_client_api::{
ExecutorProvider, CallExecutor
};
use sc_client::Client;
use sc_chain_spec::{RuntimeGenesis, Extension};
use sc_chain_spec::get_extension;
use sp_consensus::import_queue::ImportQueue;
use futures::{
Future, FutureExt, StreamExt,
@@ -119,10 +119,10 @@ pub type BackgroundTask = Pin<Box<dyn Future<Output=()> + Send>>;
/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of
/// generics is done when you call `build`.
///
pub struct ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
pub struct ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TExPool, TRpc, Backend>
{
config: Configuration<TGen, TCSExt>,
config: Configuration,
pub (crate) client: Arc<TCl>,
backend: Arc<Backend>,
tasks_builder: TaskManagerBuilder,
@@ -193,24 +193,20 @@ type TFullParts<TBl, TRtApi, TExecDisp> = (
);
/// Creates a new full client for the given config.
pub fn new_full_client<TBl, TRtApi, TExecDisp, TGen, TCSExt>(
config: &Configuration<TGen, TCSExt>,
pub fn new_full_client<TBl, TRtApi, TExecDisp>(
config: &Configuration,
) -> Result<TFullClient<TBl, TRtApi, TExecDisp>, Error> where
TBl: BlockT,
TExecDisp: NativeExecutionDispatch + 'static,
TGen: sp_runtime::BuildStorage + serde::Serialize + for<'de> serde::Deserialize<'de>,
TCSExt: Extension,
{
new_full_parts(config).map(|parts| parts.0)
}
fn new_full_parts<TBl, TRtApi, TExecDisp, TGen, TCSExt>(
config: &Configuration<TGen, TCSExt>,
fn new_full_parts<TBl, TRtApi, TExecDisp>(
config: &Configuration,
) -> Result<TFullParts<TBl, TRtApi, TExecDisp>, Error> where
TBl: BlockT,
TExecDisp: NativeExecutionDispatch + 'static,
TGen: sp_runtime::BuildStorage + serde::Serialize + for<'de> serde::Deserialize<'de>,
TCSExt: Extension,
{
let keystore = match &config.keystore {
KeystoreConfig::Path { path, password } => Keystore::open(
@@ -230,15 +226,11 @@ fn new_full_parts<TBl, TRtApi, TExecDisp, TGen, TCSExt>(
);
let chain_spec = config.expect_chain_spec();
let fork_blocks = chain_spec
.extensions()
.get::<sc_client::ForkBlocks<TBl>>()
let fork_blocks = get_extension::<sc_client::ForkBlocks<TBl>>(chain_spec.extensions())
.cloned()
.unwrap_or_default();
let bad_blocks = chain_spec
.extensions()
.get::<sc_client::BadBlocks<TBl>>()
let bad_blocks = get_extension::<sc_client::BadBlocks<TBl>>(chain_spec.extensions())
.cloned()
.unwrap_or_default();
@@ -267,7 +259,7 @@ fn new_full_parts<TBl, TRtApi, TExecDisp, TGen, TCSExt>(
sc_client_db::new_client(
db_config,
executor,
config.expect_chain_spec(),
config.expect_chain_spec().as_storage_builder(),
fork_blocks,
bad_blocks,
extensions,
@@ -278,16 +270,13 @@ fn new_full_parts<TBl, TRtApi, TExecDisp, TGen, TCSExt>(
Ok((client, backend, keystore, tasks_builder))
}
impl<TGen, TCSExt> ServiceBuilder<(), (), TGen, TCSExt, (), (), (), (), (), (), (), (), ()>
where TGen: RuntimeGenesis, TCSExt: Extension {
impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> {
/// Start the service builder with a configuration.
pub fn new_full<TBl: BlockT, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>(
config: Configuration<TGen, TCSExt>
config: Configuration,
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TGen,
TCSExt,
TFullClient<TBl, TRtApi, TExecDisp>,
Arc<OnDemand<TBl>>,
(),
@@ -323,12 +312,10 @@ where TGen: RuntimeGenesis, TCSExt: Extension {
/// Start the service builder with a configuration.
pub fn new_light<TBl: BlockT, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>(
config: Configuration<TGen, TCSExt>
config: Configuration,
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TGen,
TCSExt,
TLightClient<TBl, TRtApi, TExecDisp>,
Arc<OnDemand<TBl>>,
(),
@@ -386,7 +373,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension {
let remote_blockchain = backend.remote_blockchain();
let client = Arc::new(sc_client::light::new_light(
backend.clone(),
config.expect_chain_spec(),
config.expect_chain_spec().as_storage_builder(),
executor,
config.prometheus_config.as_ref().map(|config| config.registry.clone()),
)?);
@@ -411,8 +398,8 @@ where TGen: RuntimeGenesis, TCSExt: Extension {
}
}
impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TExPool, TRpc, Backend> {
/// Returns a reference to the client that was stored in this builder.
@@ -458,9 +445,9 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
pub fn with_opt_select_chain<USc>(
self,
select_chain_builder: impl FnOnce(
&Configuration<TGen, TCSExt>, &Arc<Backend>
&Configuration, &Arc<Backend>,
) -> Result<Option<USc>, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
TExPool, TRpc, Backend>, Error> {
let select_chain = select_chain_builder(&self.config, &self.backend)?;
@@ -486,8 +473,8 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
/// Defines which head-of-chain strategy to use.
pub fn with_select_chain<USc>(
self,
builder: impl FnOnce(&Configuration<TGen, TCSExt>, &Arc<Backend>) -> Result<USc, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
builder: impl FnOnce(&Configuration, &Arc<Backend>) -> Result<USc, Error>,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, USc, TImpQu, TFprb, TFpp,
TExPool, TRpc, Backend>, Error> {
self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some))
}
@@ -495,9 +482,9 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
/// Defines which import queue to use.
pub fn with_import_queue<UImpQu>(
self,
builder: impl FnOnce(&Configuration<TGen, TCSExt>, Arc<TCl>, Option<TSc>, Arc<TExPool>)
builder: impl FnOnce(&Configuration, Arc<TCl>, Option<TSc>, Arc<TExPool>)
-> Result<UImpQu, Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
TExPool, TRpc, Backend>, Error>
where TSc: Clone {
let import_queue = builder(
@@ -533,8 +520,6 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TGen,
TCSExt,
TCl,
TFchr,
TSc,
@@ -573,8 +558,6 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
) -> Result<ServiceBuilder<
TBl,
TRtApi,
TGen,
TCSExt,
TCl,
TFchr,
TSc,
@@ -592,14 +575,14 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
pub fn with_import_queue_and_opt_fprb<UImpQu, UFprb>(
self,
builder: impl FnOnce(
&Configuration<TGen, TCSExt>,
&Configuration,
Arc<TCl>,
Arc<Backend>,
Option<TFchr>,
Option<TSc>,
Arc<TExPool>,
) -> Result<(UImpQu, Option<UFprb>), Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
TExPool, TRpc, Backend>, Error>
where TSc: Clone, TFchr: Clone {
let (import_queue, fprb) = builder(
@@ -634,14 +617,14 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
pub fn with_import_queue_and_fprb<UImpQu, UFprb>(
self,
builder: impl FnOnce(
&Configuration<TGen, TCSExt>,
&Configuration,
Arc<TCl>,
Arc<Backend>,
Option<TFchr>,
Option<TSc>,
Arc<TExPool>,
) -> Result<(UImpQu, UFprb), Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
TExPool, TRpc, Backend>, Error>
where TSc: Clone, TFchr: Clone {
self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx|
@@ -658,7 +641,7 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
Arc<TCl>,
Option<TFchr>,
) -> Result<(UExPool, Option<BackgroundTask>), Error>
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
UExPool, TRpc, Backend>, Error>
where TSc: Clone, TFchr: Clone {
let (transaction_pool, background_task) = transaction_pool_builder(
@@ -694,7 +677,7 @@ impl<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, T
pub fn with_rpc_extensions<URpc>(
self,
rpc_ext_builder: impl FnOnce(&Self) -> Result<URpc, Error>,
) -> Result<ServiceBuilder<TBl, TRtApi, TGen, TCSExt, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
TExPool, URpc, Backend>, Error>
where TSc: Clone, TFchr: Clone {
let rpc_extensions = rpc_ext_builder(&self)?;
@@ -755,12 +738,10 @@ pub trait ServiceBuilderCommand {
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send>>;
}
impl<TBl, TRtApi, TGen, TCSExt, TBackend, TExec, TSc, TImpQu, TExPool, TRpc>
impl<TBl, TRtApi, TBackend, TExec, TSc, TImpQu, TExPool, TRpc>
ServiceBuilder<
TBl,
TRtApi,
TGen,
TCSExt,
Client<TBackend, TExec, TBl, TRtApi>,
Arc<OnDemand<TBl>>,
TSc,
@@ -781,8 +762,6 @@ ServiceBuilder<
sp_api::ApiExt<TBl, StateBackend = TBackend::State>,
TBl: BlockT,
TRtApi: 'static + Send + Sync,
TGen: RuntimeGenesis,
TCSExt: Extension,
TBackend: 'static + sc_client_api::backend::Backend<TBl> + Send,
TExec: 'static + sc_client::CallExecutor<TBl> + Send + Sync + Clone,
TSc: Clone,
+5 -8
View File
@@ -19,7 +19,7 @@
use crate::error;
use crate::builder::{ServiceBuilderCommand, ServiceBuilder};
use crate::error::Error;
use sc_chain_spec::{ChainSpec, RuntimeGenesis, Extension};
use sc_chain_spec::ChainSpec;
use log::{warn, info};
use futures::{future, prelude::*};
use sp_runtime::traits::{
@@ -38,19 +38,16 @@ use std::{io::{Read, Write, Seek}, pin::Pin};
use sc_client_api::BlockBody;
/// Build a chain spec json
pub fn build_spec<G, E>(spec: ChainSpec<G, E>, raw: bool) -> error::Result<String> where
G: RuntimeGenesis,
E: Extension,
{
Ok(spec.to_json(raw)?)
pub fn build_spec(spec: &dyn ChainSpec, raw: bool) -> error::Result<String> {
Ok(spec.as_json(raw)?)
}
impl<
TBl, TRtApi, TGen, TCSExt, TBackend,
TBl, TRtApi, TBackend,
TExecDisp, TFchr, TSc, TImpQu, TFprb, TFpp,
TExPool, TRpc, Backend
> ServiceBuilderCommand for ServiceBuilder<
TBl, TRtApi, TGen, TCSExt,
TBl, TRtApi,
Client<TBackend, LocalCallExecutor<TBackend, NativeExecutor<TExecDisp>>, TBl, TRtApi>,
TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend
> where
+7 -7
View File
@@ -23,7 +23,7 @@ pub use sc_executor::WasmExecutionMethod;
use std::{future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc};
pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions;
use sc_chain_spec::{ChainSpec, NoExtension};
use sc_chain_spec::ChainSpec;
use sp_core::crypto::Protected;
use target_info::Target;
use sc_telemetry::TelemetryEndpoints;
@@ -51,7 +51,7 @@ pub struct VersionInfo {
}
/// Service configuration.
pub struct Configuration<G, E = NoExtension> {
pub struct Configuration {
/// Implementation name
pub impl_name: &'static str,
/// Implementation version
@@ -79,7 +79,7 @@ pub struct Configuration<G, E = NoExtension> {
/// Pruning settings.
pub pruning: PruningMode,
/// Chain configuration.
pub chain_spec: Option<ChainSpec<G, E>>,
pub chain_spec: Option<Box<dyn ChainSpec>>,
/// Node name.
pub name: String,
/// Wasm execution method.
@@ -192,7 +192,7 @@ impl PrometheusConfig {
}
}
impl<G, E> Default for Configuration<G, E> {
impl Default for Configuration {
/// Create a default config
fn default() -> Self {
Configuration {
@@ -233,7 +233,7 @@ impl<G, E> Default for Configuration<G, E> {
}
}
impl<G, E> Configuration<G, E> {
impl Configuration {
/// Create a default config using `VersionInfo`
pub fn from_version(version: &VersionInfo) -> Self {
let mut config = Configuration::default();
@@ -270,8 +270,8 @@ impl<G, E> Configuration<G, E> {
/// ### Panics
///
/// This method panic if the `chain_spec` is `None`
pub fn expect_chain_spec(&self) -> &ChainSpec<G, E> {
self.chain_spec.as_ref().expect("chain_spec must be specified")
pub fn expect_chain_spec(&self) -> &dyn ChainSpec {
&**self.chain_spec.as_ref().expect("chain_spec must be specified")
}
/// Return a reference to the `DatabaseConfig` of this `Configuration`.
+7 -5
View File
@@ -59,7 +59,9 @@ pub use self::builder::{
TFullCallExecutor, TLightCallExecutor,
};
pub use config::{Configuration, Roles, PruningMode};
pub use sc_chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension};
pub use sc_chain_spec::{
ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension
};
pub use sp_transaction_pool::{TransactionPool, InPoolTransaction, error::IntoPoolError};
pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions;
pub use sc_client::FinalityNotifications;
@@ -487,8 +489,8 @@ mod waiting {
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
#[cfg(not(target_os = "unknown"))]
fn start_rpc_servers<G, E, H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
config: &Configuration<G, E>,
fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
config: &Configuration,
mut gen_handler: H
) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
fn maybe_start_server<T, F>(address: Option<SocketAddr>, mut start: F) -> Result<Option<T>, io::Error>
@@ -528,8 +530,8 @@ fn start_rpc_servers<G, E, H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metad
/// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive.
#[cfg(target_os = "unknown")]
fn start_rpc_servers<G, E, H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
_: &Configuration<G, E>,
fn start_rpc_servers<H: FnMut() -> sc_rpc_server::RpcHandler<sc_rpc::Metadata>>(
_: &Configuration,
_: H
) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
Ok(Box::new(()))