mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-25 09:25:46 +00:00
Drop sc-client (#1037)
* WIP * collator * fix missing reference * Make collator builder more generic * all clear * revert start colator fn * fix return type of start_collator * sc-consensus * bump back to master * Update collator/src/lib.rs Co-Authored-By: Benjamin Kampmann <ben@gnunicorn.org> * Update collator/src/lib.rs Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * uncomment type MaxIterations * reactivate append storage feature Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org> Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
Generated
+166
-185
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@ codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive
|
|||||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
client = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
|
client = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ structopt = "0.3.8"
|
|||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
+50
-70
@@ -15,9 +15,8 @@
|
|||||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use sp_runtime::traits::BlakeTwo256;
|
use service::{IdentifyVariant, self};
|
||||||
use service::{IdentifyVariant, Block, self, RuntimeApiCollection, TFullClient};
|
use sc_executor::NativeExecutionDispatch;
|
||||||
use sp_api::ConstructRuntimeApi;
|
|
||||||
use sc_cli::{SubstrateCli, Result};
|
use sc_cli::{SubstrateCli, Result};
|
||||||
use crate::cli::{Cli, Subcommand};
|
use crate::cli::{Cli, Subcommand};
|
||||||
|
|
||||||
@@ -82,23 +81,56 @@ pub fn run() -> Result<()> {
|
|||||||
info!(" KUSAMA FOUNDATION ");
|
info!(" KUSAMA FOUNDATION ");
|
||||||
info!("----------------------------");
|
info!("----------------------------");
|
||||||
|
|
||||||
run_node::<
|
runtime.run_node(
|
||||||
service::kusama_runtime::RuntimeApi,
|
|config| {
|
||||||
service::KusamaExecutor,
|
service::kusama_new_light(config)
|
||||||
service::kusama_runtime::UncheckedExtrinsic,
|
},
|
||||||
>(runtime, authority_discovery_enabled, grandpa_pause)
|
|config| {
|
||||||
|
service::kusama_new_full(
|
||||||
|
config,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
authority_discovery_enabled,
|
||||||
|
6000,
|
||||||
|
grandpa_pause
|
||||||
|
).map(|(s, _, _)| s)
|
||||||
|
},
|
||||||
|
service::KusamaExecutor::native_version().runtime_version
|
||||||
|
)
|
||||||
} else if config.chain_spec.is_westend() {
|
} else if config.chain_spec.is_westend() {
|
||||||
run_node::<
|
runtime.run_node(
|
||||||
service::westend_runtime::RuntimeApi,
|
|config| {
|
||||||
service::WestendExecutor,
|
service::westend_new_light(config)
|
||||||
service::westend_runtime::UncheckedExtrinsic,
|
},
|
||||||
>(runtime, authority_discovery_enabled, grandpa_pause)
|
|config| {
|
||||||
|
service::westend_new_full(
|
||||||
|
config,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
authority_discovery_enabled,
|
||||||
|
6000,
|
||||||
|
grandpa_pause
|
||||||
|
).map(|(s, _, _)| s)
|
||||||
|
},
|
||||||
|
service::WestendExecutor::native_version().runtime_version
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
run_node::<
|
runtime.run_node(
|
||||||
service::polkadot_runtime::RuntimeApi,
|
|config| {
|
||||||
service::PolkadotExecutor,
|
service::polkadot_new_light(config)
|
||||||
service::polkadot_runtime::UncheckedExtrinsic,
|
},
|
||||||
>(runtime, authority_discovery_enabled, grandpa_pause)
|
|config| {
|
||||||
|
service::polkadot_new_full(
|
||||||
|
config,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
authority_discovery_enabled,
|
||||||
|
6000,
|
||||||
|
grandpa_pause
|
||||||
|
).map(|(s, _, _)| s)
|
||||||
|
},
|
||||||
|
service::PolkadotExecutor::native_version().runtime_version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(Subcommand::Base(subcommand)) => {
|
Some(Subcommand::Base(subcommand)) => {
|
||||||
@@ -160,55 +192,3 @@ pub fn run() -> Result<()> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_node<R, D, E>(
|
|
||||||
runtime: sc_cli::Runner<Cli>,
|
|
||||||
authority_discovery_enabled: bool,
|
|
||||||
grandpa_pause: Option<(u32, u32)>,
|
|
||||||
) -> sc_cli::Result<()>
|
|
||||||
where
|
|
||||||
R: ConstructRuntimeApi<Block, service::TFullClient<Block, R, D>>
|
|
||||||
+ Send + Sync + 'static,
|
|
||||||
<R as ConstructRuntimeApi<Block, service::TFullClient<Block, R, D>>>::RuntimeApi:
|
|
||||||
RuntimeApiCollection<E, StateBackend = sc_client_api::StateBackendFor<service::TFullBackend<Block>, Block>>,
|
|
||||||
<R as ConstructRuntimeApi<Block, service::TLightClient<Block, R, D>>>::RuntimeApi:
|
|
||||||
RuntimeApiCollection<E, StateBackend = sc_client_api::StateBackendFor<service::TLightBackend<Block>, Block>>,
|
|
||||||
E: service::Codec + Send + Sync + 'static,
|
|
||||||
D: service::NativeExecutionDispatch + 'static,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
<<R as ConstructRuntimeApi<Block, TFullClient<Block, R, D>>>::RuntimeApi as sp_api::ApiExt<Block>>::StateBackend:
|
|
||||||
sp_api::StateBackend<BlakeTwo256>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/43580
|
|
||||||
R: ConstructRuntimeApi<
|
|
||||||
Block,
|
|
||||||
TLightClient<R, D>
|
|
||||||
>,
|
|
||||||
{
|
|
||||||
runtime.run_node(
|
|
||||||
|config| service::new_light::<R, D, E>(config),
|
|
||||||
|config| service::new_full::<R, D, E>(
|
|
||||||
config,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
authority_discovery_enabled,
|
|
||||||
6000,
|
|
||||||
grandpa_pause,
|
|
||||||
).map(|(s, _)| s),
|
|
||||||
D::native_version().runtime_version,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't simply use `service::TLightClient` due to a
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/43580
|
|
||||||
type TLightClient<Runtime, Dispatch> = sc_client::Client<
|
|
||||||
sc_client::light::backend::Backend<sc_client_db::light::LightStorage<Block>, BlakeTwo256>,
|
|
||||||
sc_client::light::call_executor::GenesisCallExecutor<
|
|
||||||
sc_client::light::backend::Backend<sc_client_db::light::LightStorage<Block>, BlakeTwo256>,
|
|
||||||
sc_client::LocalCallExecutor<
|
|
||||||
sc_client::light::backend::Backend<sc_client_db::light::LightStorage<Block>, BlakeTwo256>,
|
|
||||||
sc_executor::NativeExecutor<Dispatch>
|
|
||||||
>
|
|
||||||
>,
|
|
||||||
Block,
|
|
||||||
Runtime
|
|
||||||
>;
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.4"
|
futures = "0.3.4"
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -52,9 +52,8 @@ use std::pin::Pin;
|
|||||||
|
|
||||||
use futures::{future, Future, Stream, FutureExt, TryFutureExt, StreamExt, task::Spawn};
|
use futures::{future, Future, Stream, FutureExt, TryFutureExt, StreamExt, task::Spawn};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use sc_client::BlockchainEvents;
|
use sc_client_api::StateBackend;
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use sp_runtime::traits::BlakeTwo256;
|
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
BlockId, Hash, Block,
|
BlockId, Hash, Block,
|
||||||
parachain::{
|
parachain::{
|
||||||
@@ -72,7 +71,9 @@ pub use polkadot_validation::SignedStatement;
|
|||||||
pub use polkadot_primitives::parachain::CollatorId;
|
pub use polkadot_primitives::parachain::CollatorId;
|
||||||
pub use sc_network::PeerId;
|
pub use sc_network::PeerId;
|
||||||
pub use service::RuntimeApiCollection;
|
pub use service::RuntimeApiCollection;
|
||||||
|
use sc_service::ClientProvider;
|
||||||
pub use sc_cli::SubstrateCli;
|
pub use sc_cli::SubstrateCli;
|
||||||
|
use sp_api::{ConstructRuntimeApi, ApiExt, HashFor};
|
||||||
|
|
||||||
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
|
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||||
|
|
||||||
@@ -114,34 +115,24 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Polkadot client type.
|
|
||||||
pub type PolkadotClient<B, E, R> = sc_client::Client<B, E, Block, R>;
|
|
||||||
|
|
||||||
/// Something that can build a `ParachainContext`.
|
/// Something that can build a `ParachainContext`.
|
||||||
pub trait BuildParachainContext {
|
pub trait BuildParachainContext {
|
||||||
/// The parachain context produced by the `build` function.
|
/// The parachain context produced by the `build` function.
|
||||||
type ParachainContext: self::ParachainContext;
|
type ParachainContext: self::ParachainContext;
|
||||||
|
|
||||||
/// Build the `ParachainContext`.
|
/// Build the `ParachainContext`.
|
||||||
fn build<B, E, R, SP, Extrinsic>(
|
fn build<Client, SP, Extrinsic>(
|
||||||
self,
|
self,
|
||||||
client: Arc<PolkadotClient<B, E, R>>,
|
client: Arc<Client>,
|
||||||
spawner: SP,
|
spawner: SP,
|
||||||
network: impl Network + Clone + 'static,
|
network: impl Network + Clone + 'static,
|
||||||
) -> Result<Self::ParachainContext, ()>
|
) -> Result<Self::ParachainContext, ()>
|
||||||
where
|
where
|
||||||
PolkadotClient<B, E, R>: ProvideRuntimeApi<Block>,
|
Client: ProvideRuntimeApi<Block>,
|
||||||
<PolkadotClient<B, E, R> as ProvideRuntimeApi<Block>>::Api: RuntimeApiCollection<Extrinsic>,
|
Client::Api: RuntimeApiCollection<Extrinsic>,
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
<Client::Api as ApiExt<Block>>::StateBackend: StateBackend<HashFor<Block>>,
|
||||||
<<PolkadotClient<B, E, R> as ProvideRuntimeApi<Block>>::Api as sp_api::ApiExt<Block>>::StateBackend:
|
|
||||||
sp_api::StateBackend<BlakeTwo256>,
|
|
||||||
Extrinsic: codec::Codec + Send + Sync + 'static,
|
Extrinsic: codec::Codec + Send + Sync + 'static,
|
||||||
E: sc_client::CallExecutor<Block> + Clone + Send + Sync + 'static,
|
SP: Spawn + Clone + Send + Sync + 'static;
|
||||||
SP: Spawn + Clone + Send + Sync + 'static,
|
|
||||||
R: Send + Sync + 'static,
|
|
||||||
B: sc_client_api::Backend<Block> + 'static,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
B::State: sp_api::StateBackend<BlakeTwo256>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parachain context needed for collation.
|
/// Parachain context needed for collation.
|
||||||
@@ -209,38 +200,40 @@ pub async fn collate<P>(
|
|||||||
Ok(collation)
|
Ok(collation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_collator_service<S, P, Extrinsic>(
|
|
||||||
service: (S, polkadot_service::FullNodeHandles),
|
fn build_collator_service<SP, P, C, E, R, Extrinsic>(
|
||||||
|
spawner: SP,
|
||||||
|
handles: polkadot_service::FullNodeHandles,
|
||||||
|
client: Arc<C>,
|
||||||
para_id: ParaId,
|
para_id: ParaId,
|
||||||
key: Arc<CollatorPair>,
|
key: Arc<CollatorPair>,
|
||||||
build_parachain_context: P,
|
build_parachain_context: P,
|
||||||
) -> Result<S, polkadot_service::Error>
|
) -> Result<impl Future<Output = ()> + Send + 'static, polkadot_service::Error>
|
||||||
where
|
where
|
||||||
S: AbstractService<Block = service::Block>,
|
C: ClientProvider<
|
||||||
sc_client::Client<S::Backend, S::CallExecutor, service::Block, S::RuntimeApi>: ProvideRuntimeApi<Block>,
|
service::Block,
|
||||||
<sc_client::Client<S::Backend, S::CallExecutor, service::Block, S::RuntimeApi> as ProvideRuntimeApi<Block>>::Api:
|
service::TFullBackend<service::Block>,
|
||||||
RuntimeApiCollection<
|
service::TFullCallExecutor<service::Block, E>,
|
||||||
|
R
|
||||||
|
> + 'static,
|
||||||
|
R: ConstructRuntimeApi<service::Block, C> + Sync + Send,
|
||||||
|
<R as ConstructRuntimeApi<service::Block, C>>::RuntimeApi:
|
||||||
|
sp_api::ApiExt<
|
||||||
|
service::Block,
|
||||||
|
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||||
|
>
|
||||||
|
+ RuntimeApiCollection<
|
||||||
Extrinsic,
|
Extrinsic,
|
||||||
Error = sp_blockchain::Error,
|
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||||
StateBackend = sc_client_api::StateBackendFor<S::Backend, Block>
|
>
|
||||||
>,
|
+ Sync + Send,
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
E: sc_executor::NativeExecutionDispatch + 'static,
|
||||||
S::Backend: service::Backend<service::Block>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
<S::Backend as service::Backend<service::Block>>::State:
|
|
||||||
sp_api::StateBackend<sp_runtime::traits::HashFor<Block>>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
S::CallExecutor: service::CallExecutor<service::Block>,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
S::SelectChain: service::SelectChain<service::Block>,
|
|
||||||
P: BuildParachainContext,
|
P: BuildParachainContext,
|
||||||
P::ParachainContext: Send + 'static,
|
P::ParachainContext: Send + 'static,
|
||||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||||
Extrinsic: service::Codec + Send + Sync + 'static,
|
Extrinsic: service::Codec + Send + Sync + 'static,
|
||||||
|
SP: Spawn + Clone + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let (service, handles) = service;
|
|
||||||
let spawner = service.spawn_task_handle();
|
|
||||||
|
|
||||||
let polkadot_network = handles.polkadot_network
|
let polkadot_network = handles.polkadot_network
|
||||||
.ok_or_else(|| "Collator cannot run when Polkadot-specific networking has not been started")?;
|
.ok_or_else(|| "Collator cannot run when Polkadot-specific networking has not been started")?;
|
||||||
|
|
||||||
@@ -250,8 +243,6 @@ fn build_collator_service<S, P, Extrinsic>(
|
|||||||
handles.validation_service_handle
|
handles.validation_service_handle
|
||||||
.ok_or_else(|| "Collator cannot run when validation networking has not been started")?;
|
.ok_or_else(|| "Collator cannot run when validation networking has not been started")?;
|
||||||
|
|
||||||
let client = service.client();
|
|
||||||
|
|
||||||
let parachain_context = match build_parachain_context.build(
|
let parachain_context = match build_parachain_context.build(
|
||||||
client.clone(),
|
client.clone(),
|
||||||
spawner,
|
spawner,
|
||||||
@@ -334,9 +325,7 @@ fn build_collator_service<S, P, Extrinsic>(
|
|||||||
}
|
}
|
||||||
}.boxed();
|
}.boxed();
|
||||||
|
|
||||||
service.spawn_essential_task("collation", work);
|
Ok(work)
|
||||||
|
|
||||||
Ok(service)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Async function that will run the collator node with the given `RelayChainContext` and `ParachainContext`
|
/// Async function that will run the collator node with the given `RelayChainContext` and `ParachainContext`
|
||||||
@@ -348,29 +337,55 @@ pub async fn start_collator<P>(
|
|||||||
config: Configuration,
|
config: Configuration,
|
||||||
) -> Result<(), polkadot_service::Error>
|
) -> Result<(), polkadot_service::Error>
|
||||||
where
|
where
|
||||||
P: BuildParachainContext,
|
P: 'static + BuildParachainContext,
|
||||||
P::ParachainContext: Send + 'static,
|
P::ParachainContext: Send + 'static,
|
||||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||||
{
|
{
|
||||||
let is_kusama = config.chain_spec.is_kusama();
|
let is_kusama = config.chain_spec.is_kusama();
|
||||||
match (is_kusama, &config.role) {
|
match (is_kusama, &config.role) {
|
||||||
(_, Role::Light) => return Err(
|
(_, Role::Light) => Err(
|
||||||
polkadot_service::Error::Other("light nodes are unsupported as collator".into())
|
polkadot_service::Error::Other("light nodes are unsupported as collator".into())
|
||||||
).into(),
|
).into(),
|
||||||
(true, _) =>
|
(true, _) => {
|
||||||
|
let (service, client, handlers) = service::kusama_new_full(
|
||||||
|
config,
|
||||||
|
Some((key.public(), para_id)),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
6000,
|
||||||
|
None
|
||||||
|
)?;
|
||||||
|
let spawn_handle = service.spawn_task_handle();
|
||||||
build_collator_service(
|
build_collator_service(
|
||||||
service::kusama_new_full(config, Some((key.public(), para_id)), None, false, 6000, None)?,
|
spawn_handle,
|
||||||
|
handlers,
|
||||||
|
client,
|
||||||
|
para_id,
|
||||||
|
key,
|
||||||
|
build_parachain_context
|
||||||
|
)?.await;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
(false, _) => {
|
||||||
|
let (service, client, handles) = service::polkadot_new_full(
|
||||||
|
config,
|
||||||
|
Some((key.public(), para_id)),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
6000,
|
||||||
|
None
|
||||||
|
)?;
|
||||||
|
let spawn_handle = service.spawn_task_handle();
|
||||||
|
build_collator_service(
|
||||||
|
spawn_handle,
|
||||||
|
handles,
|
||||||
|
client,
|
||||||
para_id,
|
para_id,
|
||||||
key,
|
key,
|
||||||
build_parachain_context,
|
build_parachain_context,
|
||||||
)?.await,
|
)?.await;
|
||||||
(false, _) =>
|
Ok(())
|
||||||
build_collator_service(
|
}
|
||||||
service::polkadot_new_full(config, Some((key.public(), para_id)), None, false, 6000, None)?,
|
|
||||||
para_id,
|
|
||||||
key,
|
|
||||||
build_parachain_context,
|
|
||||||
)?.await,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,9 +428,9 @@ mod tests {
|
|||||||
impl BuildParachainContext for BuildDummyParachainContext {
|
impl BuildParachainContext for BuildDummyParachainContext {
|
||||||
type ParachainContext = DummyParachainContext;
|
type ParachainContext = DummyParachainContext;
|
||||||
|
|
||||||
fn build<B, E, R, SP, Extrinsic>(
|
fn build<C, SP, Extrinsic>(
|
||||||
self,
|
self,
|
||||||
_: Arc<PolkadotClient<B, E, R>>,
|
_: Arc<C>,
|
||||||
_: SP,
|
_: SP,
|
||||||
_: impl Network + Clone + 'static,
|
_: impl Network + Clone + 'static,
|
||||||
) -> Result<Self::ParachainContext, ()> {
|
) -> Result<Self::ParachainContext, ()> {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ futures = "0.3.4"
|
|||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
exit-future = "0.2.0"
|
exit-future = "0.2.0"
|
||||||
futures-timer = "2.0"
|
futures-timer = "2.0"
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
wasm-timer = "0.2.4"
|
wasm-timer = "0.2.4"
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ log = "0.4.8"
|
|||||||
parking_lot = "0.10.0"
|
parking_lot = "0.10.0"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-service = { git = "https://github.com/paritytech/substrate", features = ["test-helpers"], branch = "master" }
|
||||||
sc-network-test = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network-test = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ use sc_client_api::{
|
|||||||
client::BlockBackend,
|
client::BlockBackend,
|
||||||
backend::{TransactionFor, AuxStore, Backend, Finalizer},
|
backend::{TransactionFor, AuxStore, Backend, Finalizer},
|
||||||
};
|
};
|
||||||
|
use sc_consensus::LongestChain;
|
||||||
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
|
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
|
||||||
use sc_client::LongestChain;
|
|
||||||
use sp_consensus::block_validation::DefaultBlockAnnounceValidator;
|
use sp_consensus::block_validation::DefaultBlockAnnounceValidator;
|
||||||
use sp_consensus::import_queue::{
|
use sp_consensus::import_queue::{
|
||||||
BasicQueue, BoxJustificationImport, Verifier, BoxFinalityProofImport,
|
BasicQueue, BoxJustificationImport, Verifier, BoxFinalityProofImport,
|
||||||
@@ -53,14 +53,23 @@ use sp_runtime::generic::BlockId;
|
|||||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
pub use sc_network_test::PassThroughVerifier;
|
pub use sc_network_test::PassThroughVerifier;
|
||||||
|
use sc_service::client::Client;
|
||||||
|
|
||||||
pub use polkadot_test_runtime_client::runtime::{Block, Extrinsic, Hash};
|
pub use polkadot_test_runtime_client::runtime::{Block, Extrinsic, Hash};
|
||||||
pub use polkadot_test_runtime_client::{TestClient, TestClientBuilder, TestClientBuilderExt};
|
pub use polkadot_test_runtime_client::{TestClient, TestClientBuilder, TestClientBuilderExt};
|
||||||
|
|
||||||
pub type PeersFullClient =
|
pub type PeersFullClient = Client<
|
||||||
sc_client::Client<polkadot_test_runtime_client::Backend, polkadot_test_runtime_client::Executor, Block, polkadot_test_runtime_client::runtime::RuntimeApi>;
|
polkadot_test_runtime_client::Backend,
|
||||||
pub type PeersLightClient =
|
polkadot_test_runtime_client::Executor,
|
||||||
sc_client::Client<polkadot_test_runtime_client::LightBackend, polkadot_test_runtime_client::LightExecutor, Block, polkadot_test_runtime_client::runtime::RuntimeApi>;
|
Block,
|
||||||
|
polkadot_test_runtime_client::runtime::RuntimeApi
|
||||||
|
>;
|
||||||
|
pub type PeersLightClient = Client<
|
||||||
|
polkadot_test_runtime_client::LightBackend,
|
||||||
|
polkadot_test_runtime_client::LightExecutor,
|
||||||
|
Block,
|
||||||
|
polkadot_test_runtime_client::runtime::RuntimeApi
|
||||||
|
>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum PeersClient {
|
pub enum PeersClient {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ parachain = { package = "polkadot-parachain", path = "../../.." }
|
|||||||
collator = { package = "polkadot-collator", path = "../../../../collator" }
|
collator = { package = "polkadot-collator", path = "../../../../collator" }
|
||||||
primitives = { package = "polkadot-primitives", path = "../../../../primitives" }
|
primitives = { package = "polkadot-primitives", path = "../../../../primitives" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
client = { package = "sc-client", git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
client-api = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
|
client-api = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
parking_lot = "0.10.0"
|
parking_lot = "0.10.0"
|
||||||
codec = { package = "parity-scale-codec", version = "1.2.0" }
|
codec = { package = "parity-scale-codec", version = "1.2.0" }
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ impl ParachainContext for AdderContext {
|
|||||||
impl BuildParachainContext for AdderContext {
|
impl BuildParachainContext for AdderContext {
|
||||||
type ParachainContext = Self;
|
type ParachainContext = Self;
|
||||||
|
|
||||||
fn build<B, E, R, SP, Extrinsic>(
|
fn build<Client, SP, Extrinsic>(
|
||||||
self,
|
self,
|
||||||
_: Arc<collator::PolkadotClient<B, E, R>>,
|
_: Arc<Client>,
|
||||||
_: SP,
|
_: SP,
|
||||||
network: impl Network + Clone + 'static,
|
network: impl Network + Clone + 'static,
|
||||||
) -> Result<Self::ParachainContext, ()> {
|
) -> Result<Self::ParachainContext, ()> {
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = { package = "sc-client", git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
jsonrpc-core = "14.0.3"
|
jsonrpc-core = "14.0.3"
|
||||||
polkadot-primitives = { path = "../primitives" }
|
polkadot-primitives = { path = "../primitives" }
|
||||||
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ use std::sync::Arc;
|
|||||||
use polkadot_primitives::{Block, AccountId, Nonce, Balance};
|
use polkadot_primitives::{Block, AccountId, Nonce, Balance};
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::ProvideRuntimeApi;
|
||||||
use txpool_api::TransactionPool;
|
use txpool_api::TransactionPool;
|
||||||
|
use sp_blockchain::HeaderBackend;
|
||||||
|
use sc_client_api::light::{Fetcher, RemoteBlockchain};
|
||||||
|
|
||||||
/// A type representing all RPC extensions.
|
/// A type representing all RPC extensions.
|
||||||
pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
||||||
@@ -30,7 +32,7 @@ pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
|||||||
/// Instantiate all RPC extensions.
|
/// Instantiate all RPC extensions.
|
||||||
pub fn create_full<C, P, UE>(client: Arc<C>, pool: Arc<P>) -> RpcExtension where
|
pub fn create_full<C, P, UE>(client: Arc<C>, pool: Arc<P>) -> RpcExtension where
|
||||||
C: ProvideRuntimeApi<Block>,
|
C: ProvideRuntimeApi<Block>,
|
||||||
C: client::blockchain::HeaderBackend<Block>,
|
C: HeaderBackend<Block>,
|
||||||
C: Send + Sync + 'static,
|
C: Send + Sync + 'static,
|
||||||
C::Api: frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
|
C::Api: frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
|
||||||
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance, UE>,
|
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance, UE>,
|
||||||
@@ -53,18 +55,18 @@ pub fn create_full<C, P, UE>(client: Arc<C>, pool: Arc<P>) -> RpcExtension where
|
|||||||
/// Instantiate all RPC extensions for light node.
|
/// Instantiate all RPC extensions for light node.
|
||||||
pub fn create_light<C, P, F, UE>(
|
pub fn create_light<C, P, F, UE>(
|
||||||
client: Arc<C>,
|
client: Arc<C>,
|
||||||
remote_blockchain: Arc<dyn client::light::blockchain::RemoteBlockchain<Block>>,
|
remote_blockchain: Arc<dyn RemoteBlockchain<Block>>,
|
||||||
fetcher: Arc<F>,
|
fetcher: Arc<F>,
|
||||||
pool: Arc<P>,
|
pool: Arc<P>,
|
||||||
) -> RpcExtension
|
) -> RpcExtension
|
||||||
where
|
where
|
||||||
C: ProvideRuntimeApi<Block>,
|
C: ProvideRuntimeApi<Block>,
|
||||||
C: client::blockchain::HeaderBackend<Block>,
|
C: HeaderBackend<Block>,
|
||||||
C: Send + Sync + 'static,
|
C: Send + Sync + 'static,
|
||||||
C::Api: frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
|
C::Api: frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
|
||||||
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance, UE>,
|
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance, UE>,
|
||||||
P: TransactionPool + Sync + Send + 'static,
|
P: TransactionPool + Sync + Send + 'static,
|
||||||
F: client::light::fetcher::Fetcher<Block> + 'static,
|
F: Fetcher<Block> + 'static,
|
||||||
UE: codec::Codec + Send + Sync + 'static,
|
UE: codec::Codec + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
use frame_rpc_system::{LightSystem, SystemApi};
|
use frame_rpc_system::{LightSystem, SystemApi};
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ license = "GPL-3.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["test-helpers"], default-features = false }
|
||||||
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
polkadot-test-runtime = { path = ".." }
|
polkadot-test-runtime = { path = ".." }
|
||||||
@@ -17,6 +19,5 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
codec = { package = "parity-scale-codec", version = "1.0.0" }
|
codec = { package = "parity-scale-codec", version = "1.0.0" }
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
|
|||||||
@@ -22,16 +22,19 @@ use std::sync::Arc;
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
pub use substrate_test_client::*;
|
pub use substrate_test_client::*;
|
||||||
pub use polkadot_test_runtime as runtime;
|
pub use polkadot_test_runtime as runtime;
|
||||||
pub use sc_client::LongestChain;
|
|
||||||
|
|
||||||
use sp_core::{sr25519, ChangesTrieConfiguration, map, twox_128};
|
use sp_core::{sr25519, ChangesTrieConfiguration, map, twox_128};
|
||||||
use sp_core::storage::{ChildInfo, Storage, StorageChild};
|
use sp_core::storage::{ChildInfo, Storage, StorageChild};
|
||||||
use polkadot_test_runtime::genesismap::GenesisConfig;
|
use polkadot_test_runtime::genesismap::GenesisConfig;
|
||||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, HashFor};
|
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, HashFor};
|
||||||
use sc_client::{
|
use sc_consensus::LongestChain;
|
||||||
light::fetcher::{
|
use sc_client_api::light::{RemoteCallRequest, RemoteBodyRequest};
|
||||||
RemoteCallRequest, RemoteBodyRequest,
|
use sc_service::client::{
|
||||||
|
light::{
|
||||||
|
call_executor::GenesisCallExecutor, backend as light_backend,
|
||||||
|
new_light_blockchain, new_light_backend,
|
||||||
},
|
},
|
||||||
|
genesis, Client as SubstrateClient, LocalCallExecutor
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A prelude to import in tests.
|
/// A prelude to import in tests.
|
||||||
@@ -57,7 +60,7 @@ sc_executor::native_executor_instance! {
|
|||||||
pub type Backend = substrate_test_client::Backend<polkadot_test_runtime::Block>;
|
pub type Backend = substrate_test_client::Backend<polkadot_test_runtime::Block>;
|
||||||
|
|
||||||
/// Test client executor.
|
/// Test client executor.
|
||||||
pub type Executor = sc_client::LocalCallExecutor<
|
pub type Executor = LocalCallExecutor<
|
||||||
Backend,
|
Backend,
|
||||||
NativeExecutor<LocalExecutor>,
|
NativeExecutor<LocalExecutor>,
|
||||||
>;
|
>;
|
||||||
@@ -66,10 +69,10 @@ pub type Executor = sc_client::LocalCallExecutor<
|
|||||||
pub type LightBackend = substrate_test_client::LightBackend<polkadot_test_runtime::Block>;
|
pub type LightBackend = substrate_test_client::LightBackend<polkadot_test_runtime::Block>;
|
||||||
|
|
||||||
/// Test client light executor.
|
/// Test client light executor.
|
||||||
pub type LightExecutor = sc_client::light::call_executor::GenesisCallExecutor<
|
pub type LightExecutor = GenesisCallExecutor<
|
||||||
LightBackend,
|
LightBackend,
|
||||||
sc_client::LocalCallExecutor<
|
LocalCallExecutor<
|
||||||
sc_client::light::backend::Backend<
|
light_backend::Backend<
|
||||||
sc_client_db::light::LightStorage<polkadot_test_runtime::Block>,
|
sc_client_db::light::LightStorage<polkadot_test_runtime::Block>,
|
||||||
HashFor<polkadot_test_runtime::Block>
|
HashFor<polkadot_test_runtime::Block>
|
||||||
>,
|
>,
|
||||||
@@ -120,7 +123,7 @@ impl substrate_test_client::GenesisInit for GenesisParameters {
|
|||||||
let state_root = <<<runtime::Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
|
let state_root = <<<runtime::Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
|
||||||
storage.top.clone().into_iter().chain(child_roots).collect()
|
storage.top.clone().into_iter().chain(child_roots).collect()
|
||||||
);
|
);
|
||||||
let block: runtime::Block = sc_client::genesis::construct_genesis_block(state_root);
|
let block: runtime::Block = genesis::construct_genesis_block(state_root);
|
||||||
storage.top.extend(additional_storage_with_genesis(&block));
|
storage.top.extend(additional_storage_with_genesis(&block));
|
||||||
|
|
||||||
storage
|
storage
|
||||||
@@ -136,9 +139,9 @@ pub type TestClientBuilder<E, B> = substrate_test_client::TestClientBuilder<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
/// Test client type with `LocalExecutor` and generic Backend.
|
/// Test client type with `LocalExecutor` and generic Backend.
|
||||||
pub type Client<B> = sc_client::Client<
|
pub type Client<B> = SubstrateClient<
|
||||||
B,
|
B,
|
||||||
sc_client::LocalCallExecutor<B, sc_executor::NativeExecutor<LocalExecutor>>,
|
LocalCallExecutor<B, sc_executor::NativeExecutor<LocalExecutor>>,
|
||||||
polkadot_test_runtime::Block,
|
polkadot_test_runtime::Block,
|
||||||
polkadot_test_runtime::RuntimeApi,
|
polkadot_test_runtime::RuntimeApi,
|
||||||
>;
|
>;
|
||||||
@@ -212,21 +215,21 @@ pub trait TestClientBuilderExt<B>: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build the test client and longest chain selector.
|
/// Build the test client and longest chain selector.
|
||||||
fn build_with_longest_chain(self) -> (Client<B>, sc_client::LongestChain<B, polkadot_test_runtime::Block>);
|
fn build_with_longest_chain(self) -> (Client<B>, LongestChain<B, polkadot_test_runtime::Block>);
|
||||||
|
|
||||||
/// Build the test client and the backend.
|
/// Build the test client and the backend.
|
||||||
fn build_with_backend(self) -> (Client<B>, Arc<B>);
|
fn build_with_backend(self) -> (Client<B>, Arc<B>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestClientBuilderExt<Backend> for TestClientBuilder<
|
impl TestClientBuilderExt<Backend> for TestClientBuilder<
|
||||||
sc_client::LocalCallExecutor<Backend, sc_executor::NativeExecutor<LocalExecutor>>,
|
LocalCallExecutor<Backend, sc_executor::NativeExecutor<LocalExecutor>>,
|
||||||
Backend
|
Backend
|
||||||
> {
|
> {
|
||||||
fn genesis_init_mut(&mut self) -> &mut GenesisParameters {
|
fn genesis_init_mut(&mut self) -> &mut GenesisParameters {
|
||||||
Self::genesis_init_mut(self)
|
Self::genesis_init_mut(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_with_longest_chain(self) -> (Client<Backend>, sc_client::LongestChain<Backend, polkadot_test_runtime::Block>) {
|
fn build_with_longest_chain(self) -> (Client<Backend>, LongestChain<Backend, polkadot_test_runtime::Block>) {
|
||||||
self.build_with_native_executor(None)
|
self.build_with_native_executor(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,15 +280,25 @@ pub fn new() -> Client<Backend> {
|
|||||||
|
|
||||||
/// Creates new light client instance used for tests.
|
/// Creates new light client instance used for tests.
|
||||||
pub fn new_light() -> (
|
pub fn new_light() -> (
|
||||||
sc_client::Client<LightBackend, LightExecutor, polkadot_test_runtime::Block, polkadot_test_runtime::RuntimeApi>,
|
SubstrateClient<
|
||||||
|
LightBackend,
|
||||||
|
LightExecutor,
|
||||||
|
polkadot_test_runtime::Block,
|
||||||
|
polkadot_test_runtime::RuntimeApi
|
||||||
|
>,
|
||||||
Arc<LightBackend>,
|
Arc<LightBackend>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
let storage = sc_client_db::light::LightStorage::new_test();
|
let storage = sc_client_db::light::LightStorage::new_test();
|
||||||
let blockchain = Arc::new(sc_client::light::blockchain::Blockchain::new(storage));
|
let blockchain =new_light_blockchain(storage);
|
||||||
let backend = Arc::new(LightBackend::new(blockchain.clone()));
|
let backend = new_light_backend(blockchain.clone());
|
||||||
let executor = new_native_executor();
|
let executor = new_native_executor();
|
||||||
let local_call_executor = sc_client::LocalCallExecutor::new(backend.clone(), executor, sp_core::tasks::executor(), Default::default(),);
|
let local_call_executor = LocalCallExecutor::new(
|
||||||
|
backend.clone(),
|
||||||
|
executor,
|
||||||
|
sp_core::tasks::executor(),
|
||||||
|
Default::default()
|
||||||
|
);
|
||||||
let call_executor = LightExecutor::new(
|
let call_executor = LightExecutor::new(
|
||||||
backend.clone(),
|
backend.clone(),
|
||||||
local_call_executor,
|
local_call_executor,
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
@@ -37,6 +37,7 @@ grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.co
|
|||||||
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" }
|
telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ const DEFAULT_PROTOCOL_ID: &str = "dot";
|
|||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Extensions {
|
pub struct Extensions {
|
||||||
/// Block numbers with known hashes.
|
/// Block numbers with known hashes.
|
||||||
pub fork_blocks: sc_client::ForkBlocks<polkadot_primitives::Block>,
|
pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::Block>,
|
||||||
/// Known bad block hashes.
|
/// Known bad block hashes.
|
||||||
pub bad_blocks: sc_client::BadBlocks<polkadot_primitives::Block>,
|
pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `ChainSpec parametrised for polkadot runtime`.
|
/// The `ChainSpec parametrised for polkadot runtime`.
|
||||||
|
|||||||
+408
-456
@@ -19,7 +19,6 @@
|
|||||||
pub mod chain_spec;
|
pub mod chain_spec;
|
||||||
mod grandpa_support;
|
mod grandpa_support;
|
||||||
|
|
||||||
use sc_client::LongestChain;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use polkadot_primitives::{parachain, Hash, BlockId, AccountId, Nonce, Balance};
|
use polkadot_primitives::{parachain, Hash, BlockId, AccountId, Nonce, Balance};
|
||||||
@@ -27,21 +26,20 @@ use polkadot_primitives::{parachain, Hash, BlockId, AccountId, Nonce, Balance};
|
|||||||
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
|
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
|
||||||
use service::{error::Error as ServiceError, ServiceBuilder};
|
use service::{error::Error as ServiceError, ServiceBuilder};
|
||||||
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
|
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
|
||||||
use inherents::InherentDataProviders;
|
|
||||||
use sc_executor::native_executor_instance;
|
use sc_executor::native_executor_instance;
|
||||||
use log::info;
|
use log::info;
|
||||||
pub use service::{
|
pub use service::{
|
||||||
AbstractService, Role, PruningMode, TransactionPoolOptions, Error, RuntimeGenesis,
|
AbstractService, Role, PruningMode, TransactionPoolOptions, Error, RuntimeGenesis,
|
||||||
TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor,
|
TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor,
|
||||||
Configuration, ChainSpec, ServiceBuilderCommand,
|
Configuration, ChainSpec, ServiceBuilderCommand, ClientProvider,
|
||||||
};
|
};
|
||||||
pub use service::config::{DatabaseConfig, PrometheusConfig};
|
pub use service::config::{DatabaseConfig, PrometheusConfig};
|
||||||
pub use sc_executor::NativeExecutionDispatch;
|
pub use sc_executor::NativeExecutionDispatch;
|
||||||
pub use sc_client::{ExecutionStrategy, CallExecutor, Client};
|
pub use sc_client_api::{Backend, ExecutionStrategy, CallExecutor};
|
||||||
pub use sc_client_api::backend::Backend;
|
pub use sc_consensus::LongestChain;
|
||||||
pub use sp_api::{Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
|
pub use sp_api::{Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
|
||||||
pub use sp_runtime::traits::{HashFor, NumberFor};
|
pub use sp_runtime::traits::{HashFor, NumberFor};
|
||||||
pub use consensus_common::SelectChain;
|
pub use consensus_common::{SelectChain, BlockImport, block_validation::Chain};
|
||||||
pub use polkadot_primitives::parachain::{CollatorId, ParachainHost};
|
pub use polkadot_primitives::parachain::{CollatorId, ParachainHost};
|
||||||
pub use polkadot_primitives::Block;
|
pub use polkadot_primitives::Block;
|
||||||
pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256};
|
pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256};
|
||||||
@@ -76,7 +74,7 @@ native_executor_instance!(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// A set of APIs that polkadot-like runtimes must implement.
|
/// A set of APIs that polkadot-like runtimes must implement.
|
||||||
pub trait RuntimeApiCollection<Extrinsic: codec::Codec + Send + Sync + 'static> :
|
pub trait RuntimeApiCollection<Extrinsic: codec::Codec + Send + Sync + 'static>:
|
||||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||||
+ babe_primitives::BabeApi<Block>
|
+ babe_primitives::BabeApi<Block>
|
||||||
@@ -156,7 +154,7 @@ macro_rules! new_full_start {
|
|||||||
Block, $runtime, $executor
|
Block, $runtime, $executor
|
||||||
>($config)?
|
>($config)?
|
||||||
.with_select_chain(|_, backend| {
|
.with_select_chain(|_, backend| {
|
||||||
Ok(sc_client::LongestChain::new(backend.clone()))
|
Ok(sc_consensus::LongestChain::new(backend.clone()))
|
||||||
})?
|
})?
|
||||||
.with_transaction_pool(|config, client, _fetcher, prometheus_registry| {
|
.with_transaction_pool(|config, client, _fetcher, prometheus_registry| {
|
||||||
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
||||||
@@ -209,6 +207,352 @@ macro_rules! new_full_start {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds a new service for a full client.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! new_full {
|
||||||
|
(
|
||||||
|
$config:expr,
|
||||||
|
$collating_for:expr,
|
||||||
|
$max_block_data_size:expr,
|
||||||
|
$authority_discovery_enabled:expr,
|
||||||
|
$slot_duration:expr,
|
||||||
|
$grandpa_pause:expr,
|
||||||
|
$runtime:ty,
|
||||||
|
$dispatch:ty
|
||||||
|
) => {{
|
||||||
|
use sc_network::Event;
|
||||||
|
use sc_client_api::ExecutorProvider;
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
|
||||||
|
let is_collator = $collating_for.is_some();
|
||||||
|
let role = $config.role.clone();
|
||||||
|
let is_authority = role.is_authority() && !is_collator;
|
||||||
|
let force_authoring = $config.force_authoring;
|
||||||
|
let max_block_data_size = $max_block_data_size;
|
||||||
|
let db_path = match $config.database.path() {
|
||||||
|
Some(path) => std::path::PathBuf::from(path),
|
||||||
|
None => return Err("Starting a Polkadot service with a custom database isn't supported".to_string().into()),
|
||||||
|
};
|
||||||
|
let disable_grandpa = $config.disable_grandpa;
|
||||||
|
let name = $config.network.node_name.clone();
|
||||||
|
let authority_discovery_enabled = $authority_discovery_enabled;
|
||||||
|
let slot_duration = $slot_duration;
|
||||||
|
|
||||||
|
let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config, $runtime, $dispatch);
|
||||||
|
|
||||||
|
let backend = builder.backend().clone();
|
||||||
|
|
||||||
|
let service = builder
|
||||||
|
.with_finality_proof_provider(|client, backend| {
|
||||||
|
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
||||||
|
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
|
||||||
|
})?
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
let (block_import, link_half, babe_link) = import_setup.take()
|
||||||
|
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
|
||||||
|
|
||||||
|
let client = service.client();
|
||||||
|
let known_oracle = client.clone();
|
||||||
|
|
||||||
|
let mut handles = FullNodeHandles::default();
|
||||||
|
let select_chain = if let Some(select_chain) = service.select_chain() {
|
||||||
|
select_chain
|
||||||
|
} else {
|
||||||
|
info!("The node cannot start as an authority because it can't select chain.");
|
||||||
|
return Ok((service, client, handles));
|
||||||
|
};
|
||||||
|
let gossip_validator_select_chain = select_chain.clone();
|
||||||
|
|
||||||
|
let is_known = move |block_hash: &Hash| {
|
||||||
|
use consensus_common::BlockStatus;
|
||||||
|
|
||||||
|
match known_oracle.block_status(&BlockId::hash(*block_hash)) {
|
||||||
|
Err(_) | Ok(BlockStatus::Unknown) | Ok(BlockStatus::Queued) => None,
|
||||||
|
Ok(BlockStatus::KnownBad) => Some(Known::Bad),
|
||||||
|
Ok(BlockStatus::InChainWithState) | Ok(BlockStatus::InChainPruned) => {
|
||||||
|
match gossip_validator_select_chain.leaves() {
|
||||||
|
Err(_) => None,
|
||||||
|
Ok(leaves) => if leaves.contains(block_hash) {
|
||||||
|
Some(Known::Leaf)
|
||||||
|
} else {
|
||||||
|
Some(Known::Old)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let polkadot_network_service = network_protocol::start(
|
||||||
|
service.network(),
|
||||||
|
network_protocol::Config {
|
||||||
|
collating_for: $collating_for,
|
||||||
|
},
|
||||||
|
(is_known, client.clone()),
|
||||||
|
client.clone(),
|
||||||
|
service.spawn_task_handle(),
|
||||||
|
).map_err(|e| format!("Could not spawn network worker: {:?}", e))?;
|
||||||
|
|
||||||
|
let authority_handles = if is_collator || role.is_authority() {
|
||||||
|
let availability_store = {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
let mut path = PathBuf::from(db_path);
|
||||||
|
path.push("availability");
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "unknown"))]
|
||||||
|
{
|
||||||
|
av_store::Store::new(
|
||||||
|
::av_store::Config {
|
||||||
|
cache_size: None,
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
polkadot_network_service.clone(),
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "unknown")]
|
||||||
|
av_store::Store::new_in_memory(gossip)
|
||||||
|
};
|
||||||
|
|
||||||
|
polkadot_network_service.register_availability_store(availability_store.clone());
|
||||||
|
|
||||||
|
let (validation_service_handle, validation_service) = consensus::ServiceBuilder {
|
||||||
|
client: client.clone(),
|
||||||
|
network: polkadot_network_service.clone(),
|
||||||
|
collators: polkadot_network_service.clone(),
|
||||||
|
spawner: service.spawn_task_handle(),
|
||||||
|
availability_store: availability_store.clone(),
|
||||||
|
select_chain: select_chain.clone(),
|
||||||
|
keystore: service.keystore(),
|
||||||
|
max_block_data_size,
|
||||||
|
}.build();
|
||||||
|
|
||||||
|
service.spawn_essential_task("validation-service", Box::pin(validation_service));
|
||||||
|
|
||||||
|
handles.validation_service_handle = Some(validation_service_handle.clone());
|
||||||
|
|
||||||
|
Some((validation_service_handle, availability_store))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if role.is_authority() {
|
||||||
|
let (validation_service_handle, availability_store) = authority_handles
|
||||||
|
.clone()
|
||||||
|
.expect("Authority handles are set for authority nodes; qed");
|
||||||
|
|
||||||
|
let proposer = consensus::ProposerFactory::new(
|
||||||
|
client.clone(),
|
||||||
|
service.transaction_pool(),
|
||||||
|
validation_service_handle,
|
||||||
|
slot_duration,
|
||||||
|
backend,
|
||||||
|
);
|
||||||
|
|
||||||
|
let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?;
|
||||||
|
let can_author_with =
|
||||||
|
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
|
||||||
|
|
||||||
|
let block_import = availability_store.block_import(
|
||||||
|
block_import,
|
||||||
|
client.clone(),
|
||||||
|
service.spawn_task_handle(),
|
||||||
|
service.keystore(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let babe_config = babe::BabeParams {
|
||||||
|
keystore: service.keystore(),
|
||||||
|
client: client.clone(),
|
||||||
|
select_chain,
|
||||||
|
block_import,
|
||||||
|
env: proposer,
|
||||||
|
sync_oracle: service.network(),
|
||||||
|
inherent_data_providers: inherent_data_providers.clone(),
|
||||||
|
force_authoring,
|
||||||
|
babe_link,
|
||||||
|
can_author_with,
|
||||||
|
};
|
||||||
|
|
||||||
|
let babe = babe::start_babe(babe_config)?;
|
||||||
|
service.spawn_essential_task("babe", babe);
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches!(role, Role::Authority{..} | Role::Sentry{..}) {
|
||||||
|
if authority_discovery_enabled {
|
||||||
|
let (sentries, authority_discovery_role) = match role {
|
||||||
|
Role::Authority { ref sentry_nodes } => (
|
||||||
|
sentry_nodes.clone(),
|
||||||
|
authority_discovery::Role::Authority (
|
||||||
|
service.keystore(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Role::Sentry {..} => (
|
||||||
|
vec![],
|
||||||
|
authority_discovery::Role::Sentry,
|
||||||
|
),
|
||||||
|
_ => unreachable!("Due to outer matches! constraint; qed."),
|
||||||
|
};
|
||||||
|
|
||||||
|
let network = service.network();
|
||||||
|
let network_event_stream = network.event_stream("authority-discovery");
|
||||||
|
let dht_event_stream = network_event_stream.filter_map(|e| async move { match e {
|
||||||
|
Event::Dht(e) => Some(e),
|
||||||
|
_ => None,
|
||||||
|
}}).boxed();
|
||||||
|
let authority_discovery = authority_discovery::AuthorityDiscovery::new(
|
||||||
|
service.client(),
|
||||||
|
network,
|
||||||
|
sentries,
|
||||||
|
dht_event_stream,
|
||||||
|
authority_discovery_role,
|
||||||
|
service.prometheus_registry(),
|
||||||
|
);
|
||||||
|
|
||||||
|
service.spawn_task("authority-discovery", authority_discovery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 = if is_authority {
|
||||||
|
Some(service.keystore())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let config = 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,
|
||||||
|
is_authority: role.is_network_authority(),
|
||||||
|
};
|
||||||
|
|
||||||
|
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 voting_rule = match $grandpa_pause {
|
||||||
|
Some((block, delay)) => {
|
||||||
|
info!("GRANDPA scheduled voting pause set for block #{} with a duration of {} blocks.",
|
||||||
|
block,
|
||||||
|
delay,
|
||||||
|
);
|
||||||
|
|
||||||
|
grandpa::VotingRulesBuilder::default()
|
||||||
|
.add(grandpa_support::PauseAfterBlockFor(block, delay))
|
||||||
|
.build()
|
||||||
|
},
|
||||||
|
None =>
|
||||||
|
grandpa::VotingRulesBuilder::default()
|
||||||
|
.build(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let grandpa_config = grandpa::GrandpaParams {
|
||||||
|
config,
|
||||||
|
link: link_half,
|
||||||
|
network: service.network(),
|
||||||
|
inherent_data_providers: inherent_data_providers.clone(),
|
||||||
|
telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
|
||||||
|
voting_rule,
|
||||||
|
prometheus_registry: service.prometheus_registry(),
|
||||||
|
};
|
||||||
|
|
||||||
|
service.spawn_essential_task(
|
||||||
|
"grandpa-voter",
|
||||||
|
grandpa::run_grandpa_voter(grandpa_config)?
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
grandpa::setup_disabled_grandpa(
|
||||||
|
client.clone(),
|
||||||
|
&inherent_data_providers,
|
||||||
|
service.network(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
handles.polkadot_network = Some(polkadot_network_service);
|
||||||
|
(service, client, handles)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new service for a light client.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! new_light {
|
||||||
|
($config:expr, $runtime:ty, $dispatch:ty) => {{
|
||||||
|
crate::set_prometheus_registry(&mut $config)?;
|
||||||
|
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||||
|
|
||||||
|
ServiceBuilder::new_light::<Block, $runtime, $dispatch>($config)?
|
||||||
|
.with_select_chain(|_, backend| {
|
||||||
|
Ok(sc_consensus::LongestChain::new(backend.clone()))
|
||||||
|
})?
|
||||||
|
.with_transaction_pool(|config, client, fetcher, prometheus_registry| {
|
||||||
|
let fetcher = fetcher
|
||||||
|
.ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
|
||||||
|
let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone());
|
||||||
|
let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
|
||||||
|
config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light,
|
||||||
|
);
|
||||||
|
Ok(pool)
|
||||||
|
})?
|
||||||
|
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _| {
|
||||||
|
let fetch_checker = fetcher
|
||||||
|
.map(|fetcher| fetcher.checker().clone())
|
||||||
|
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
||||||
|
let grandpa_block_import = grandpa::light_block_import(
|
||||||
|
client.clone(), backend, &(client.clone() as Arc<_>), Arc::new(fetch_checker)
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let finality_proof_import = grandpa_block_import.clone();
|
||||||
|
let finality_proof_request_builder =
|
||||||
|
finality_proof_import.create_finality_proof_request_builder();
|
||||||
|
|
||||||
|
let (babe_block_import, babe_link) = babe::block_import(
|
||||||
|
babe::Config::get_or_compute(&*client)?,
|
||||||
|
grandpa_block_import,
|
||||||
|
client.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
||||||
|
let import_queue = babe::import_queue(
|
||||||
|
babe_link,
|
||||||
|
babe_block_import,
|
||||||
|
None,
|
||||||
|
Some(Box::new(finality_proof_import)),
|
||||||
|
client,
|
||||||
|
inherent_data_providers.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok((import_queue, finality_proof_request_builder))
|
||||||
|
})?
|
||||||
|
.with_finality_proof_provider(|client, backend| {
|
||||||
|
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
||||||
|
Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _)
|
||||||
|
})?
|
||||||
|
.with_rpc_extensions(|builder|
|
||||||
|
-> Result<polkadot_rpc::RpcExtension, _> {
|
||||||
|
let fetcher = builder.fetcher()
|
||||||
|
.ok_or_else(|| "Trying to start node RPC without active fetcher")?;
|
||||||
|
let remote_blockchain = builder.remote_backend()
|
||||||
|
.ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
|
||||||
|
|
||||||
|
Ok(polkadot_rpc::create_light(builder.client().clone(), remote_blockchain, fetcher, builder.pool()))
|
||||||
|
})?
|
||||||
|
.build()
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds a new object suitable for chain operations.
|
/// Builds a new object suitable for chain operations.
|
||||||
pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration)
|
pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration)
|
||||||
-> Result<impl ServiceBuilderCommand<Block=Block>, ServiceError>
|
-> Result<impl ServiceBuilderCommand<Block=Block>, ServiceError>
|
||||||
@@ -227,7 +571,7 @@ where
|
|||||||
/// Create a new Polkadot service for a full node.
|
/// Create a new Polkadot service for a full node.
|
||||||
#[cfg(feature = "full-node")]
|
#[cfg(feature = "full-node")]
|
||||||
pub fn polkadot_new_full(
|
pub fn polkadot_new_full(
|
||||||
config: Configuration,
|
mut config: Configuration,
|
||||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||||
max_block_data_size: Option<u64>,
|
max_block_data_size: Option<u64>,
|
||||||
authority_discovery_enabled: bool,
|
authority_discovery_enabled: bool,
|
||||||
@@ -235,61 +579,69 @@ pub fn polkadot_new_full(
|
|||||||
grandpa_pause: Option<(u32, u32)>,
|
grandpa_pause: Option<(u32, u32)>,
|
||||||
)
|
)
|
||||||
-> Result<(
|
-> Result<(
|
||||||
impl AbstractService<
|
impl AbstractService,
|
||||||
Block = Block,
|
Arc<impl ClientProvider<
|
||||||
RuntimeApi = polkadot_runtime::RuntimeApi,
|
Block,
|
||||||
Backend = TFullBackend<Block>,
|
TFullBackend<Block>,
|
||||||
SelectChain = LongestChain<TFullBackend<Block>, Block>,
|
TFullCallExecutor<Block, PolkadotExecutor>,
|
||||||
CallExecutor = TFullCallExecutor<Block, PolkadotExecutor>,
|
polkadot_runtime::RuntimeApi
|
||||||
>,
|
>>,
|
||||||
FullNodeHandles,
|
FullNodeHandles,
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
new_full(
|
let (service, client, handles) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
authority_discovery_enabled,
|
authority_discovery_enabled,
|
||||||
slot_duration,
|
slot_duration,
|
||||||
grandpa_pause,
|
grandpa_pause,
|
||||||
)
|
polkadot_runtime::RuntimeApi,
|
||||||
|
PolkadotExecutor
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((service, client, handles))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Kusama service for a full node.
|
/// Create a new Kusama service for a full node.
|
||||||
#[cfg(feature = "full-node")]
|
#[cfg(feature = "full-node")]
|
||||||
pub fn kusama_new_full(
|
pub fn kusama_new_full(
|
||||||
config: Configuration,
|
mut config: Configuration,
|
||||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||||
max_block_data_size: Option<u64>,
|
max_block_data_size: Option<u64>,
|
||||||
authority_discovery_enabled: bool,
|
authority_discovery_enabled: bool,
|
||||||
slot_duration: u64,
|
slot_duration: u64,
|
||||||
grandpa_pause: Option<(u32, u32)>,
|
grandpa_pause: Option<(u32, u32)>,
|
||||||
)
|
) -> Result<(
|
||||||
-> Result<(
|
impl AbstractService,
|
||||||
impl AbstractService<
|
Arc<impl ClientProvider<
|
||||||
Block = Block,
|
Block,
|
||||||
RuntimeApi = kusama_runtime::RuntimeApi,
|
TFullBackend<Block>,
|
||||||
Backend = TFullBackend<Block>,
|
TFullCallExecutor<Block, KusamaExecutor>,
|
||||||
SelectChain = LongestChain<TFullBackend<Block>, Block>,
|
kusama_runtime::RuntimeApi
|
||||||
CallExecutor = TFullCallExecutor<Block, KusamaExecutor>,
|
>
|
||||||
>,
|
>,
|
||||||
FullNodeHandles,
|
FullNodeHandles
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
new_full(
|
let (service, client, handles) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
authority_discovery_enabled,
|
authority_discovery_enabled,
|
||||||
slot_duration,
|
slot_duration,
|
||||||
grandpa_pause,
|
grandpa_pause,
|
||||||
)
|
kusama_runtime::RuntimeApi,
|
||||||
|
KusamaExecutor
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((service, client, handles))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Kusama service for a full node.
|
/// Create a new Kusama service for a full node.
|
||||||
#[cfg(feature = "full-node")]
|
#[cfg(feature = "full-node")]
|
||||||
pub fn westend_new_full(
|
pub fn westend_new_full(
|
||||||
config: Configuration,
|
mut config: Configuration,
|
||||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||||
max_block_data_size: Option<u64>,
|
max_block_data_size: Option<u64>,
|
||||||
authority_discovery_enabled: bool,
|
authority_discovery_enabled: bool,
|
||||||
@@ -297,24 +649,28 @@ pub fn westend_new_full(
|
|||||||
grandpa_pause: Option<(u32, u32)>,
|
grandpa_pause: Option<(u32, u32)>,
|
||||||
)
|
)
|
||||||
-> Result<(
|
-> Result<(
|
||||||
impl AbstractService<
|
impl AbstractService,
|
||||||
Block = Block,
|
Arc<impl ClientProvider<
|
||||||
RuntimeApi = westend_runtime::RuntimeApi,
|
Block,
|
||||||
Backend = TFullBackend<Block>,
|
TFullBackend<Block>,
|
||||||
SelectChain = LongestChain<TFullBackend<Block>, Block>,
|
TFullCallExecutor<Block, KusamaExecutor>,
|
||||||
CallExecutor = TFullCallExecutor<Block, KusamaExecutor>,
|
westend_runtime::RuntimeApi
|
||||||
>,
|
>>,
|
||||||
FullNodeHandles,
|
FullNodeHandles,
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
new_full(
|
let (service, client, handles) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
authority_discovery_enabled,
|
authority_discovery_enabled,
|
||||||
slot_duration,
|
slot_duration,
|
||||||
grandpa_pause,
|
grandpa_pause,
|
||||||
)
|
westend_runtime::RuntimeApi,
|
||||||
|
KusamaExecutor
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((service, client, handles))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles to other sub-services that full nodes instantiate, which consumers
|
/// Handles to other sub-services that full nodes instantiate, which consumers
|
||||||
@@ -328,305 +684,9 @@ pub struct FullNodeHandles {
|
|||||||
pub validation_service_handle: Option<consensus::ServiceHandle>,
|
pub validation_service_handle: Option<consensus::ServiceHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a new service for a full client.
|
|
||||||
#[cfg(feature = "full-node")]
|
|
||||||
pub fn new_full<Runtime, Dispatch, Extrinsic>(
|
|
||||||
mut config: Configuration,
|
|
||||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
|
||||||
max_block_data_size: Option<u64>,
|
|
||||||
authority_discovery_enabled: bool,
|
|
||||||
slot_duration: u64,
|
|
||||||
grandpa_pause: Option<(u32, u32)>,
|
|
||||||
)
|
|
||||||
-> Result<(
|
|
||||||
impl AbstractService<
|
|
||||||
Block = Block,
|
|
||||||
RuntimeApi = Runtime,
|
|
||||||
Backend = TFullBackend<Block>,
|
|
||||||
SelectChain = LongestChain<TFullBackend<Block>, Block>,
|
|
||||||
CallExecutor = TFullCallExecutor<Block, Dispatch>,
|
|
||||||
>,
|
|
||||||
FullNodeHandles,
|
|
||||||
), ServiceError>
|
|
||||||
where
|
|
||||||
Runtime: ConstructRuntimeApi<Block, service::TFullClient<Block, Runtime, Dispatch>> + Send + Sync + 'static,
|
|
||||||
Runtime::RuntimeApi:
|
|
||||||
RuntimeApiCollection<Extrinsic, StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>>,
|
|
||||||
Dispatch: NativeExecutionDispatch + 'static,
|
|
||||||
Extrinsic: RuntimeExtrinsic,
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
|
||||||
<Runtime::RuntimeApi as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
|
||||||
{
|
|
||||||
use sc_network::Event;
|
|
||||||
use sc_client_api::ExecutorProvider;
|
|
||||||
use futures::stream::StreamExt;
|
|
||||||
|
|
||||||
let is_collator = collating_for.is_some();
|
|
||||||
let role = config.role.clone();
|
|
||||||
let is_authority = role.is_authority() && !is_collator;
|
|
||||||
let force_authoring = config.force_authoring;
|
|
||||||
let max_block_data_size = max_block_data_size;
|
|
||||||
let db_path = match config.database.path() {
|
|
||||||
Some(path) => std::path::PathBuf::from(path),
|
|
||||||
None => return Err("Starting a Polkadot service with a custom database isn't supported".to_string().into()),
|
|
||||||
};
|
|
||||||
let disable_grandpa = config.disable_grandpa;
|
|
||||||
let name = config.network.node_name.clone();
|
|
||||||
let authority_discovery_enabled = authority_discovery_enabled;
|
|
||||||
let slot_duration = slot_duration;
|
|
||||||
|
|
||||||
let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config, Runtime, Dispatch);
|
|
||||||
|
|
||||||
let backend = builder.backend().clone();
|
|
||||||
|
|
||||||
let service = builder
|
|
||||||
.with_finality_proof_provider(|client, backend| {
|
|
||||||
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
|
||||||
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
|
|
||||||
})?
|
|
||||||
.build()?;
|
|
||||||
|
|
||||||
let (block_import, link_half, babe_link) = import_setup.take()
|
|
||||||
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
|
|
||||||
|
|
||||||
let client = service.client();
|
|
||||||
let known_oracle = client.clone();
|
|
||||||
|
|
||||||
let mut handles = FullNodeHandles::default();
|
|
||||||
let select_chain = if let Some(select_chain) = service.select_chain() {
|
|
||||||
select_chain
|
|
||||||
} else {
|
|
||||||
info!("The node cannot start as an authority because it can't select chain.");
|
|
||||||
return Ok((service, handles));
|
|
||||||
};
|
|
||||||
let gossip_validator_select_chain = select_chain.clone();
|
|
||||||
|
|
||||||
let is_known = move |block_hash: &Hash| {
|
|
||||||
use consensus_common::BlockStatus;
|
|
||||||
|
|
||||||
match known_oracle.block_status(&BlockId::hash(*block_hash)) {
|
|
||||||
Err(_) | Ok(BlockStatus::Unknown) | Ok(BlockStatus::Queued) => None,
|
|
||||||
Ok(BlockStatus::KnownBad) => Some(Known::Bad),
|
|
||||||
Ok(BlockStatus::InChainWithState) | Ok(BlockStatus::InChainPruned) => {
|
|
||||||
match gossip_validator_select_chain.leaves() {
|
|
||||||
Err(_) => None,
|
|
||||||
Ok(leaves) => if leaves.contains(block_hash) {
|
|
||||||
Some(Known::Leaf)
|
|
||||||
} else {
|
|
||||||
Some(Known::Old)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let polkadot_network_service = network_protocol::start(
|
|
||||||
service.network(),
|
|
||||||
network_protocol::Config {
|
|
||||||
collating_for,
|
|
||||||
},
|
|
||||||
(is_known, client.clone()),
|
|
||||||
client.clone(),
|
|
||||||
service.spawn_task_handle(),
|
|
||||||
).map_err(|e| format!("Could not spawn network worker: {:?}", e))?;
|
|
||||||
|
|
||||||
let authority_handles = if is_collator || role.is_authority() {
|
|
||||||
let availability_store = {
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
let mut path = PathBuf::from(db_path);
|
|
||||||
path.push("availability");
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "unknown"))]
|
|
||||||
{
|
|
||||||
av_store::Store::new(
|
|
||||||
::av_store::Config {
|
|
||||||
cache_size: None,
|
|
||||||
path,
|
|
||||||
},
|
|
||||||
polkadot_network_service.clone(),
|
|
||||||
)?
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "unknown")]
|
|
||||||
av_store::Store::new_in_memory(gossip)
|
|
||||||
};
|
|
||||||
|
|
||||||
polkadot_network_service.register_availability_store(availability_store.clone());
|
|
||||||
|
|
||||||
let (validation_service_handle, validation_service) = consensus::ServiceBuilder {
|
|
||||||
client: client.clone(),
|
|
||||||
network: polkadot_network_service.clone(),
|
|
||||||
collators: polkadot_network_service.clone(),
|
|
||||||
spawner: service.spawn_task_handle(),
|
|
||||||
availability_store: availability_store.clone(),
|
|
||||||
select_chain: select_chain.clone(),
|
|
||||||
keystore: service.keystore(),
|
|
||||||
max_block_data_size,
|
|
||||||
}.build();
|
|
||||||
|
|
||||||
service.spawn_essential_task("validation-service", Box::pin(validation_service));
|
|
||||||
|
|
||||||
handles.validation_service_handle = Some(validation_service_handle.clone());
|
|
||||||
|
|
||||||
Some((validation_service_handle, availability_store))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if role.is_authority() {
|
|
||||||
let (validation_service_handle, availability_store) = authority_handles
|
|
||||||
.clone()
|
|
||||||
.expect("Authority handles are set for authority nodes; qed");
|
|
||||||
|
|
||||||
let proposer = consensus::ProposerFactory::new(
|
|
||||||
client.clone(),
|
|
||||||
service.transaction_pool(),
|
|
||||||
validation_service_handle,
|
|
||||||
slot_duration,
|
|
||||||
backend,
|
|
||||||
);
|
|
||||||
|
|
||||||
let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?;
|
|
||||||
let can_author_with =
|
|
||||||
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
|
|
||||||
|
|
||||||
let block_import = availability_store.block_import(
|
|
||||||
block_import,
|
|
||||||
client.clone(),
|
|
||||||
service.spawn_task_handle(),
|
|
||||||
service.keystore(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let babe_config = babe::BabeParams {
|
|
||||||
keystore: service.keystore(),
|
|
||||||
client,
|
|
||||||
select_chain,
|
|
||||||
block_import,
|
|
||||||
env: proposer,
|
|
||||||
sync_oracle: service.network(),
|
|
||||||
inherent_data_providers: inherent_data_providers.clone(),
|
|
||||||
force_authoring,
|
|
||||||
babe_link,
|
|
||||||
can_author_with,
|
|
||||||
};
|
|
||||||
|
|
||||||
let babe = babe::start_babe(babe_config)?;
|
|
||||||
service.spawn_essential_task("babe", babe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(role, Role::Authority{..} | Role::Sentry{..}) {
|
|
||||||
if authority_discovery_enabled {
|
|
||||||
let (sentries, authority_discovery_role) = match role {
|
|
||||||
Role::Authority { ref sentry_nodes } => (
|
|
||||||
sentry_nodes.clone(),
|
|
||||||
authority_discovery::Role::Authority (
|
|
||||||
service.keystore(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Role::Sentry {..} => (
|
|
||||||
vec![],
|
|
||||||
authority_discovery::Role::Sentry,
|
|
||||||
),
|
|
||||||
_ => unreachable!("Due to outer matches! constraint; qed."),
|
|
||||||
};
|
|
||||||
|
|
||||||
let network = service.network();
|
|
||||||
let network_event_stream = network.event_stream("authority-discovery");
|
|
||||||
let dht_event_stream = network_event_stream.filter_map(|e| async move { match e {
|
|
||||||
Event::Dht(e) => Some(e),
|
|
||||||
_ => None,
|
|
||||||
}}).boxed();
|
|
||||||
let authority_discovery = authority_discovery::AuthorityDiscovery::new(
|
|
||||||
service.client(),
|
|
||||||
network,
|
|
||||||
sentries,
|
|
||||||
dht_event_stream,
|
|
||||||
authority_discovery_role,
|
|
||||||
service.prometheus_registry(),
|
|
||||||
);
|
|
||||||
|
|
||||||
service.spawn_task("authority-discovery", authority_discovery);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 = if is_authority {
|
|
||||||
Some(service.keystore())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let config = 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,
|
|
||||||
is_authority: role.is_network_authority(),
|
|
||||||
};
|
|
||||||
|
|
||||||
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 voting_rule = match grandpa_pause {
|
|
||||||
Some((block, delay)) => {
|
|
||||||
info!("GRANDPA scheduled voting pause set for block #{} with a duration of {} blocks.",
|
|
||||||
block,
|
|
||||||
delay,
|
|
||||||
);
|
|
||||||
|
|
||||||
grandpa::VotingRulesBuilder::default()
|
|
||||||
.add(grandpa_support::PauseAfterBlockFor(block, delay))
|
|
||||||
.build()
|
|
||||||
},
|
|
||||||
None =>
|
|
||||||
grandpa::VotingRulesBuilder::default()
|
|
||||||
.build(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let grandpa_config = grandpa::GrandpaParams {
|
|
||||||
config,
|
|
||||||
link: link_half,
|
|
||||||
network: service.network(),
|
|
||||||
inherent_data_providers: inherent_data_providers.clone(),
|
|
||||||
telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
|
|
||||||
voting_rule,
|
|
||||||
prometheus_registry: service.prometheus_registry(),
|
|
||||||
};
|
|
||||||
|
|
||||||
service.spawn_essential_task(
|
|
||||||
"grandpa-voter",
|
|
||||||
grandpa::run_grandpa_voter(grandpa_config)?
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
grandpa::setup_disabled_grandpa(
|
|
||||||
service.client(),
|
|
||||||
&inherent_data_providers,
|
|
||||||
service.network(),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
handles.polkadot_network = Some(polkadot_network_service);
|
|
||||||
Ok((service, handles))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new Polkadot service for a light client.
|
/// Create a new Polkadot service for a light client.
|
||||||
pub fn polkadot_new_light(
|
pub fn polkadot_new_light(mut config: Configuration) -> Result<
|
||||||
config: Configuration,
|
impl AbstractService<
|
||||||
)
|
|
||||||
-> Result<impl AbstractService<
|
|
||||||
Block = Block,
|
Block = Block,
|
||||||
RuntimeApi = polkadot_runtime::RuntimeApi,
|
RuntimeApi = polkadot_runtime::RuntimeApi,
|
||||||
Backend = TLightBackend<Block>,
|
Backend = TLightBackend<Block>,
|
||||||
@@ -634,14 +694,12 @@ pub fn polkadot_new_light(
|
|||||||
CallExecutor = TLightCallExecutor<Block, PolkadotExecutor>,
|
CallExecutor = TLightCallExecutor<Block, PolkadotExecutor>,
|
||||||
>, ServiceError>
|
>, ServiceError>
|
||||||
{
|
{
|
||||||
new_light(config)
|
new_light!(config, polkadot_runtime::RuntimeApi, PolkadotExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Kusama service for a light client.
|
/// Create a new Kusama service for a light client.
|
||||||
pub fn kusama_new_light(
|
pub fn kusama_new_light(mut config: Configuration) -> Result<
|
||||||
config: Configuration,
|
impl AbstractService<
|
||||||
)
|
|
||||||
-> Result<impl AbstractService<
|
|
||||||
Block = Block,
|
Block = Block,
|
||||||
RuntimeApi = kusama_runtime::RuntimeApi,
|
RuntimeApi = kusama_runtime::RuntimeApi,
|
||||||
Backend = TLightBackend<Block>,
|
Backend = TLightBackend<Block>,
|
||||||
@@ -649,125 +707,19 @@ pub fn kusama_new_light(
|
|||||||
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>,
|
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>,
|
||||||
>, ServiceError>
|
>, ServiceError>
|
||||||
{
|
{
|
||||||
new_light(config)
|
new_light!(config, kusama_runtime::RuntimeApi, KusamaExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Westend service for a light client.
|
/// Create a new Westend service for a light client.
|
||||||
pub fn westend_new_light(
|
pub fn westend_new_light(mut config: Configuration, ) -> Result<
|
||||||
config: Configuration,
|
impl AbstractService<
|
||||||
)
|
|
||||||
-> Result<impl AbstractService<
|
|
||||||
Block = Block,
|
Block = Block,
|
||||||
RuntimeApi = westend_runtime::RuntimeApi,
|
RuntimeApi = westend_runtime::RuntimeApi,
|
||||||
Backend = TLightBackend<Block>,
|
Backend = TLightBackend<Block>,
|
||||||
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
||||||
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>,
|
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>
|
||||||
>, ServiceError>
|
>,
|
||||||
|
ServiceError>
|
||||||
{
|
{
|
||||||
new_light(config)
|
new_light!(config, westend_runtime::RuntimeApi, KusamaExecutor)
|
||||||
}
|
|
||||||
|
|
||||||
// We can't use service::TLightClient due to
|
|
||||||
// Rust bug: https://github.com/rust-lang/rust/issues/43580
|
|
||||||
type TLocalLightClient<Runtime, Dispatch> = Client<
|
|
||||||
sc_client::light::backend::Backend<sc_client_db::light::LightStorage<Block>, BlakeTwo256>,
|
|
||||||
sc_client::light::call_executor::GenesisCallExecutor<
|
|
||||||
sc_client::light::backend::Backend<sc_client_db::light::LightStorage<Block>, BlakeTwo256>,
|
|
||||||
sc_client::LocalCallExecutor<
|
|
||||||
sc_client::light::backend::Backend<
|
|
||||||
sc_client_db::light::LightStorage<Block>,
|
|
||||||
BlakeTwo256
|
|
||||||
>,
|
|
||||||
sc_executor::NativeExecutor<Dispatch>
|
|
||||||
>
|
|
||||||
>,
|
|
||||||
Block,
|
|
||||||
Runtime
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// Builds a new service for a light client.
|
|
||||||
pub fn new_light<Runtime, Dispatch, Extrinsic>(
|
|
||||||
mut config: Configuration,
|
|
||||||
)
|
|
||||||
-> Result<impl AbstractService<
|
|
||||||
Block = Block,
|
|
||||||
RuntimeApi = Runtime,
|
|
||||||
Backend = TLightBackend<Block>,
|
|
||||||
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
|
||||||
CallExecutor = TLightCallExecutor<Block, Dispatch>,
|
|
||||||
>, ServiceError>
|
|
||||||
where
|
|
||||||
Runtime: Send + Sync + 'static,
|
|
||||||
Runtime::RuntimeApi: RuntimeApiCollection<
|
|
||||||
Extrinsic,
|
|
||||||
StateBackend = sc_client_api::StateBackendFor<TLightBackend<Block>, Block>
|
|
||||||
>,
|
|
||||||
Dispatch: NativeExecutionDispatch + 'static,
|
|
||||||
Extrinsic: RuntimeExtrinsic,
|
|
||||||
Runtime: sp_api::ConstructRuntimeApi<
|
|
||||||
Block,
|
|
||||||
TLocalLightClient<Runtime, Dispatch>,
|
|
||||||
>,
|
|
||||||
{
|
|
||||||
set_prometheus_registry(&mut config)?;
|
|
||||||
|
|
||||||
let inherent_data_providers = InherentDataProviders::new();
|
|
||||||
|
|
||||||
ServiceBuilder::new_light::<Block, Runtime, Dispatch>(config)?
|
|
||||||
.with_select_chain(|_, backend| {
|
|
||||||
Ok(LongestChain::new(backend.clone()))
|
|
||||||
})?
|
|
||||||
.with_transaction_pool(|config, client, fetcher, prometheus_registry| {
|
|
||||||
let fetcher = fetcher
|
|
||||||
.ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
|
|
||||||
let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone());
|
|
||||||
let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
|
|
||||||
config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light,
|
|
||||||
);
|
|
||||||
Ok(pool)
|
|
||||||
})?
|
|
||||||
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _| {
|
|
||||||
let fetch_checker = fetcher
|
|
||||||
.map(|fetcher| fetcher.checker().clone())
|
|
||||||
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
|
||||||
let grandpa_block_import = grandpa::light_block_import(
|
|
||||||
client.clone(), backend, &(client.clone() as Arc<_>), Arc::new(fetch_checker)
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let finality_proof_import = grandpa_block_import.clone();
|
|
||||||
let finality_proof_request_builder =
|
|
||||||
finality_proof_import.create_finality_proof_request_builder();
|
|
||||||
|
|
||||||
let (babe_block_import, babe_link) = babe::block_import(
|
|
||||||
babe::Config::get_or_compute(&*client)?,
|
|
||||||
grandpa_block_import,
|
|
||||||
client.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
|
||||||
let import_queue = babe::import_queue(
|
|
||||||
babe_link,
|
|
||||||
babe_block_import,
|
|
||||||
None,
|
|
||||||
Some(Box::new(finality_proof_import)),
|
|
||||||
client,
|
|
||||||
inherent_data_providers.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok((import_queue, finality_proof_request_builder))
|
|
||||||
})?
|
|
||||||
.with_finality_proof_provider(|client, backend| {
|
|
||||||
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
|
||||||
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
|
|
||||||
})?
|
|
||||||
.with_rpc_extensions(|builder|
|
|
||||||
-> Result<polkadot_rpc::RpcExtension, _> {
|
|
||||||
let fetcher = builder.fetcher()
|
|
||||||
.ok_or_else(|| "Trying to start node RPC without active fetcher")?;
|
|
||||||
let remote_blockchain = builder.remote_backend()
|
|
||||||
.ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
|
|
||||||
|
|
||||||
Ok(polkadot_rpc::create_light(builder.client().clone(), remote_blockchain, fetcher, builder.pool()))
|
|
||||||
})?
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user