mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-22 12:35:42 +00:00
Remove node-service (#933)
* Move `chain_spec` into `node-cli` * Fixes tests * Adds `construct_simple_service` and `construct_service_factory` macros * Remove the `node-service` crate * Add some documentation * Fixes compilation on stable
This commit is contained in:
Generated
+11
-32
@@ -1594,9 +1594,19 @@ name = "node-cli"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"node-service 0.1.0",
|
"node-executor 0.1.0",
|
||||||
|
"node-network 0.1.0",
|
||||||
|
"node-primitives 0.1.0",
|
||||||
|
"node-runtime 0.1.0",
|
||||||
|
"sr-primitives 0.1.0",
|
||||||
"substrate-cli 0.3.0",
|
"substrate-cli 0.3.0",
|
||||||
|
"substrate-network 0.1.0",
|
||||||
|
"substrate-primitives 0.1.0",
|
||||||
|
"substrate-service 0.3.0",
|
||||||
|
"substrate-service-test 0.3.0",
|
||||||
|
"substrate-transaction-pool 0.1.0",
|
||||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1713,37 +1723,6 @@ dependencies = [
|
|||||||
"substrate-primitives 0.1.0",
|
"substrate-primitives 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "node-service"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"node-consensus 0.1.0",
|
|
||||||
"node-executor 0.1.0",
|
|
||||||
"node-network 0.1.0",
|
|
||||||
"node-primitives 0.1.0",
|
|
||||||
"node-runtime 0.1.0",
|
|
||||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"sr-io 0.1.0",
|
|
||||||
"sr-primitives 0.1.0",
|
|
||||||
"substrate-client 0.1.0",
|
|
||||||
"substrate-keyring 0.1.0",
|
|
||||||
"substrate-network 0.1.0",
|
|
||||||
"substrate-primitives 0.1.0",
|
|
||||||
"substrate-service 0.3.0",
|
|
||||||
"substrate-service-test 0.3.0",
|
|
||||||
"substrate-telemetry 0.3.0",
|
|
||||||
"substrate-test-client 0.1.0",
|
|
||||||
"substrate-transaction-pool 0.1.0",
|
|
||||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodrop"
|
name = "nodrop"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ members = [
|
|||||||
"node/network",
|
"node/network",
|
||||||
"node/primitives",
|
"node/primitives",
|
||||||
"node/runtime",
|
"node/runtime",
|
||||||
"node/service",
|
|
||||||
"subkey",
|
"subkey",
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
//! Substrate service components.
|
//! Substrate service components.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@@ -39,7 +38,7 @@ use primitives::{Blake2Hasher};
|
|||||||
pub type NetworkService<F> = network::Service<
|
pub type NetworkService<F> = network::Service<
|
||||||
<F as ServiceFactory>::Block,
|
<F as ServiceFactory>::Block,
|
||||||
<F as ServiceFactory>::NetworkProtocol,
|
<F as ServiceFactory>::NetworkProtocol,
|
||||||
<F as ServiceFactory>::ExtrinsicHash,
|
<<F as ServiceFactory>::Block as BlockT>::Hash,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// Code executor type for a factory.
|
/// Code executor type for a factory.
|
||||||
@@ -121,16 +120,14 @@ impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
|
|||||||
pub trait ServiceFactory: 'static + Sized {
|
pub trait ServiceFactory: 'static + Sized {
|
||||||
/// Block type.
|
/// Block type.
|
||||||
type Block: BlockT;
|
type Block: BlockT;
|
||||||
/// Extrinsic hash type.
|
|
||||||
type ExtrinsicHash: ::std::hash::Hash + Eq + Copy + fmt::Debug + fmt::LowerHex + Serialize + DeserializeOwned + ::std::str::FromStr + Send + Sync + Default + 'static;
|
|
||||||
/// Network protocol extensions.
|
/// Network protocol extensions.
|
||||||
type NetworkProtocol: network::specialization::Specialization<Self::Block>;
|
type NetworkProtocol: network::specialization::Specialization<Self::Block>;
|
||||||
/// Chain runtime.
|
/// Chain runtime.
|
||||||
type RuntimeDispatch: NativeExecutionDispatch + Send + Sync + 'static;
|
type RuntimeDispatch: NativeExecutionDispatch + Send + Sync + 'static;
|
||||||
/// Extrinsic pool backend type for the full client.
|
/// Extrinsic pool backend type for the full client.
|
||||||
type FullTransactionPoolApi: txpool::ChainApi<Hash = Self::ExtrinsicHash, Block = Self::Block> + Send + 'static;
|
type FullTransactionPoolApi: txpool::ChainApi<Hash = <Self::Block as BlockT>::Hash, Block = Self::Block> + Send + 'static;
|
||||||
/// Extrinsic pool backend type for the light client.
|
/// Extrinsic pool backend type for the light client.
|
||||||
type LightTransactionPoolApi: txpool::ChainApi<Hash = Self::ExtrinsicHash, Block = Self::Block> + 'static;
|
type LightTransactionPoolApi: txpool::ChainApi<Hash = <Self::Block as BlockT>::Hash, Block = Self::Block> + 'static;
|
||||||
/// Genesis configuration for the runtime.
|
/// Genesis configuration for the runtime.
|
||||||
type Genesis: RuntimeGenesis;
|
type Genesis: RuntimeGenesis;
|
||||||
/// Other configuration for service members.
|
/// Other configuration for service members.
|
||||||
@@ -202,7 +199,7 @@ pub trait Components: 'static {
|
|||||||
type Executor: 'static + client::CallExecutor<FactoryBlock<Self::Factory>, Blake2Hasher> + Send + Sync;
|
type Executor: 'static + client::CallExecutor<FactoryBlock<Self::Factory>, Blake2Hasher> + Send + Sync;
|
||||||
/// Extrinsic pool type.
|
/// Extrinsic pool type.
|
||||||
type TransactionPoolApi: 'static + txpool::ChainApi<
|
type TransactionPoolApi: 'static + txpool::ChainApi<
|
||||||
Hash = <Self::Factory as ServiceFactory>::ExtrinsicHash,
|
Hash = <<Self::Factory as ServiceFactory>::Block as BlockT>::Hash,
|
||||||
Block = FactoryBlock<Self::Factory>
|
Block = FactoryBlock<Self::Factory>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,9 @@ pub mod chain_ops;
|
|||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use std::{ops::Deref, result::Result, sync::Arc};
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use keystore::Store as Keystore;
|
use keystore::Store as Keystore;
|
||||||
@@ -68,7 +69,8 @@ use client::BlockchainEvents;
|
|||||||
use runtime_primitives::traits::{Header, As};
|
use runtime_primitives::traits::{Header, As};
|
||||||
use runtime_primitives::generic::BlockId;
|
use runtime_primitives::generic::BlockId;
|
||||||
use exit_future::Signal;
|
use exit_future::Signal;
|
||||||
use tokio::runtime::TaskExecutor;
|
#[doc(hidden)]
|
||||||
|
pub use tokio::runtime::TaskExecutor;
|
||||||
use substrate_executor::NativeExecutor;
|
use substrate_executor::NativeExecutor;
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
|
|
||||||
@@ -438,3 +440,163 @@ impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<
|
|||||||
self.pool.on_broadcasted(propagations)
|
self.pool.on_broadcasted(propagations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a simple `Service` implementation.
|
||||||
|
/// This `Service` just holds an instance to a `service::Service` and implements `Deref`.
|
||||||
|
/// It also provides a `new` function that takes a `config` and a `TaskExecutor`.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! construct_simple_service {
|
||||||
|
(
|
||||||
|
$name: ident
|
||||||
|
) => {
|
||||||
|
pub struct $name<C: $crate::Components> {
|
||||||
|
inner: $crate::Service<C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: $crate::Components> $name<C> {
|
||||||
|
fn new(
|
||||||
|
config: FactoryFullConfiguration<C::Factory>,
|
||||||
|
executor: $crate::TaskExecutor
|
||||||
|
) -> $crate::Result<Self, $crate::Error> {
|
||||||
|
Ok(
|
||||||
|
Self {
|
||||||
|
inner: $crate::Service::new(config, executor)?
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: $crate::Components> $crate::Deref for $name<C> {
|
||||||
|
type Target = $crate::Service<C>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructs a service factory with the given name that implements the `ServiceFactory` trait.
|
||||||
|
/// The required parameters are required to be given in the exact order. Some parameters are followed
|
||||||
|
/// by `{}` blocks. These blocks are required and used to initialize the given parameter.
|
||||||
|
/// In these block it is required to write a closure that takes the same number of arguments,
|
||||||
|
/// the corresponding function in the `ServiceFactory` trait provides.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```nocompile
|
||||||
|
/// construct_service_factory! {
|
||||||
|
/// struct Factory {
|
||||||
|
/// // Declare the block type
|
||||||
|
/// Block = Block,
|
||||||
|
/// // Declare the network protocol and give an initializer.
|
||||||
|
/// NetworkProtocol = DemoProtocol { |config| Ok(DemoProtocol::new()) },
|
||||||
|
/// RuntimeDispatch = node_executor::Executor,
|
||||||
|
/// FullTransactionPoolApi = transaction_pool::ChainApi<FullBackend<Self>, FullExecutor<Self>, Block>
|
||||||
|
/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
|
||||||
|
/// LightTransactionPoolApi = transaction_pool::ChainApi<LightBackend<Self>, LightExecutor<Self>, Block>
|
||||||
|
/// { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
|
||||||
|
/// Genesis = GenesisConfig,
|
||||||
|
/// Configuration = (),
|
||||||
|
/// FullService = Service<FullComponents<Self>>
|
||||||
|
/// { |config, executor| Service::<FullComponents<Factory>>::new(config, executor) },
|
||||||
|
/// LightService = Service<LightComponents<Self>>
|
||||||
|
/// { |config, executor| Service::<LightComponents<Factory>>::new(config, executor) },
|
||||||
|
/// // Declare the import queue. The import queue is special as it takes two initializers.
|
||||||
|
/// // The first one is for the initializing the full import queue and the second for the
|
||||||
|
/// // light import queue.
|
||||||
|
/// ImportQueue = BasicQueue<Block, NoneVerifier>
|
||||||
|
/// { |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) }
|
||||||
|
/// { |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) },
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! construct_service_factory {
|
||||||
|
(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
struct $name:ident {
|
||||||
|
Block = $block:ty,
|
||||||
|
NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* },
|
||||||
|
RuntimeDispatch = $dispatch:ty,
|
||||||
|
FullTransactionPoolApi = $full_transaction:ty { $( $full_transaction_init:tt )* },
|
||||||
|
LightTransactionPoolApi = $light_transaction:ty { $( $light_transaction_init:tt )* },
|
||||||
|
Genesis = $genesis:ty,
|
||||||
|
Configuration = $config:ty,
|
||||||
|
FullService = $full_service:ty { $( $full_service_init:tt )* },
|
||||||
|
LightService = $light_service:ty { $( $light_service_init:tt )* },
|
||||||
|
ImportQueue = $import_queue:ty
|
||||||
|
{ $( $full_import_queue_init:tt )* }
|
||||||
|
{ $( $light_import_queue_init:tt )* },
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
$( #[$attr] )*
|
||||||
|
pub struct $name {}
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
impl $crate::ServiceFactory for $name {
|
||||||
|
type Block = $block;
|
||||||
|
type NetworkProtocol = $protocol;
|
||||||
|
type RuntimeDispatch = $dispatch;
|
||||||
|
type FullTransactionPoolApi = $full_transaction;
|
||||||
|
type LightTransactionPoolApi = $light_transaction;
|
||||||
|
type Genesis = $genesis;
|
||||||
|
type Configuration = $config;
|
||||||
|
type FullService = $full_service;
|
||||||
|
type LightService = $light_service;
|
||||||
|
type ImportQueue = $import_queue;
|
||||||
|
|
||||||
|
fn build_full_transaction_pool(
|
||||||
|
config: $crate::TransactionPoolOptions,
|
||||||
|
client: $crate::Arc<$crate::FullClient<Self>>
|
||||||
|
) -> $crate::Result<$crate::TransactionPool<Self::FullTransactionPoolApi>, $crate::Error>
|
||||||
|
{
|
||||||
|
( $( $full_transaction_init )* ) (config, client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_light_transaction_pool(
|
||||||
|
config: $crate::TransactionPoolOptions,
|
||||||
|
client: $crate::Arc<$crate::LightClient<Self>>
|
||||||
|
) -> $crate::Result<$crate::TransactionPool<Self::LightTransactionPoolApi>, $crate::Error>
|
||||||
|
{
|
||||||
|
( $( $light_transaction_init )* ) (config, client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_network_protocol(config: &$crate::FactoryFullConfiguration<Self>)
|
||||||
|
-> $crate::Result<Self::NetworkProtocol, $crate::Error>
|
||||||
|
{
|
||||||
|
( $( $protocol_init )* ) (config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_full_import_queue(
|
||||||
|
config: &$crate::FactoryFullConfiguration<Self>,
|
||||||
|
client: $crate::Arc<$crate::FullClient<Self>>,
|
||||||
|
) -> $crate::Result<Self::ImportQueue, $crate::Error> {
|
||||||
|
( $( $full_import_queue_init )* ) (config, client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_light_import_queue(
|
||||||
|
config: &FactoryFullConfiguration<Self>,
|
||||||
|
client: Arc<$crate::LightClient<Self>>,
|
||||||
|
) -> Result<Self::ImportQueue, $crate::Error> {
|
||||||
|
( $( $light_import_queue_init )* ) (config, client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_light(
|
||||||
|
config: $crate::FactoryFullConfiguration<Self>,
|
||||||
|
executor: $crate::TaskExecutor
|
||||||
|
) -> $crate::Result<Self::LightService, $crate::Error>
|
||||||
|
{
|
||||||
|
( $( $light_service_init )* ) (config, executor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_full(
|
||||||
|
config: $crate::FactoryFullConfiguration<Self>,
|
||||||
|
executor: $crate::TaskExecutor
|
||||||
|
) -> Result<Self::FullService, $crate::Error>
|
||||||
|
{
|
||||||
|
( $( $full_service_init )* ) (config, executor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,4 +9,16 @@ log = "0.4"
|
|||||||
tokio = "0.1.7"
|
tokio = "0.1.7"
|
||||||
exit-future = "0.1"
|
exit-future = "0.1"
|
||||||
substrate-cli = { path = "../../core/cli" }
|
substrate-cli = { path = "../../core/cli" }
|
||||||
node-service = { path = "../service" }
|
substrate-primitives = { path = "../../core/primitives" }
|
||||||
|
node-runtime = { path = "../runtime" }
|
||||||
|
node-primitives = { path = "../primitives" }
|
||||||
|
node-network = { path = "../network" }
|
||||||
|
hex-literal = "0.1"
|
||||||
|
substrate-service = { path = "../../core/service" }
|
||||||
|
substrate-transaction-pool = { path = "../../core/transaction-pool" }
|
||||||
|
substrate-network = { path = "../../core/network" }
|
||||||
|
sr-primitives = { path = "../../core/sr-primitives" }
|
||||||
|
node-executor = { path = "../executor" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
substrate-service-test = { path = "../../core/service/test" }
|
||||||
|
|||||||
@@ -20,11 +20,14 @@ use primitives::{AuthorityId, ed25519};
|
|||||||
use node_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
|
use node_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
|
||||||
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
|
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
|
||||||
ContractConfig, Permill, Perbill};
|
ContractConfig, Permill, Perbill};
|
||||||
use service::ChainSpec;
|
use substrate_service;
|
||||||
|
|
||||||
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
||||||
|
|
||||||
pub fn bbq_birch_config() -> Result<ChainSpec<GenesisConfig>, String> {
|
/// Specialised `ChainSpec`.
|
||||||
|
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
|
||||||
|
|
||||||
|
pub fn bbq_birch_config() -> Result<ChainSpec, String> {
|
||||||
ChainSpec::from_embedded(include_bytes!("../res/bbq-birch.json"))
|
ChainSpec::from_embedded(include_bytes!("../res/bbq-birch.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +125,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Staging testnet config.
|
/// Staging testnet config.
|
||||||
pub fn staging_testnet_config() -> ChainSpec<GenesisConfig> {
|
pub fn staging_testnet_config() -> ChainSpec {
|
||||||
let boot_nodes = vec![
|
let boot_nodes = vec![
|
||||||
];
|
];
|
||||||
ChainSpec::from_genesis(
|
ChainSpec::from_genesis(
|
||||||
@@ -227,7 +230,7 @@ fn development_config_genesis() -> GenesisConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Development config (single validator Alice)
|
/// Development config (single validator Alice)
|
||||||
pub fn development_config() -> ChainSpec<GenesisConfig> {
|
pub fn development_config() -> ChainSpec {
|
||||||
ChainSpec::from_genesis("Development", "development", development_config_genesis, vec![], None, None, None)
|
ChainSpec::from_genesis("Development", "development", development_config_genesis, vec![], None, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,18 +241,30 @@ fn local_testnet_genesis() -> GenesisConfig {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_testnet_genesis_instant() -> GenesisConfig {
|
|
||||||
let mut genesis = local_testnet_genesis();
|
|
||||||
genesis.timestamp = Some(TimestampConfig { period: 0 });
|
|
||||||
genesis
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Local testnet config (multivalidator Alice + Bob)
|
/// Local testnet config (multivalidator Alice + Bob)
|
||||||
pub fn local_testnet_config() -> ChainSpec<GenesisConfig> {
|
pub fn local_testnet_config() -> ChainSpec {
|
||||||
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None)
|
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Local testnet config (multivalidator Alice + Bob)
|
#[cfg(test)]
|
||||||
pub fn integration_test_config() -> ChainSpec<GenesisConfig> {
|
mod tests {
|
||||||
ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None)
|
use super::*;
|
||||||
|
use service_test;
|
||||||
|
use service::Factory;
|
||||||
|
|
||||||
|
fn local_testnet_genesis_instant() -> GenesisConfig {
|
||||||
|
let mut genesis = local_testnet_genesis();
|
||||||
|
genesis.timestamp = Some(TimestampConfig { period: 0 });
|
||||||
|
genesis
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Local testnet config (multivalidator Alice + Bob)
|
||||||
|
pub fn integration_test_config() -> ChainSpec {
|
||||||
|
ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_connectivity() {
|
||||||
|
service_test::connectivity::<Factory>(integration_test_config());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -22,17 +22,32 @@
|
|||||||
extern crate tokio;
|
extern crate tokio;
|
||||||
|
|
||||||
extern crate substrate_cli as cli;
|
extern crate substrate_cli as cli;
|
||||||
extern crate node_service as service;
|
extern crate substrate_primitives as primitives;
|
||||||
|
extern crate node_runtime;
|
||||||
extern crate exit_future;
|
extern crate exit_future;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate hex_literal;
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate substrate_service_test as service_test;
|
||||||
|
extern crate substrate_transaction_pool as transaction_pool;
|
||||||
|
extern crate substrate_network as network;
|
||||||
|
extern crate node_network;
|
||||||
|
extern crate sr_primitives as runtime_primitives;
|
||||||
|
extern crate node_primitives;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate substrate_service;
|
||||||
|
extern crate node_executor;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub use cli::error;
|
pub use cli::error;
|
||||||
|
mod chain_spec;
|
||||||
|
mod service;
|
||||||
|
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
pub use service::{Components as ServiceComponents, Service, CustomConfiguration, ServiceFactory};
|
|
||||||
pub use cli::{VersionInfo, IntoExit};
|
pub use cli::{VersionInfo, IntoExit};
|
||||||
|
use substrate_service::{ServiceFactory, Roles as ServiceRoles};
|
||||||
|
|
||||||
/// The chain specification option.
|
/// The chain specification option.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -49,12 +64,12 @@ pub enum ChainSpec {
|
|||||||
|
|
||||||
/// Get a chain config from a spec setting.
|
/// Get a chain config from a spec setting.
|
||||||
impl ChainSpec {
|
impl ChainSpec {
|
||||||
pub(crate) fn load(self) -> Result<service::ChainSpec, String> {
|
pub(crate) fn load(self) -> Result<chain_spec::ChainSpec, String> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
ChainSpec::BbqBirch => service::chain_spec::bbq_birch_config()?,
|
ChainSpec::BbqBirch => chain_spec::bbq_birch_config()?,
|
||||||
ChainSpec::Development => service::chain_spec::development_config(),
|
ChainSpec::Development => chain_spec::development_config(),
|
||||||
ChainSpec::LocalTestnet => service::chain_spec::local_testnet_config(),
|
ChainSpec::LocalTestnet => chain_spec::local_testnet_config(),
|
||||||
ChainSpec::StagingTestnet => service::chain_spec::staging_testnet_config(),
|
ChainSpec::StagingTestnet => chain_spec::staging_testnet_config(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +84,7 @@ impl ChainSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_spec(id: &str) -> Result<Option<service::ChainSpec>, String> {
|
fn load_spec(id: &str) -> Result<Option<chain_spec::ChainSpec>, String> {
|
||||||
Ok(match ChainSpec::from(id) {
|
Ok(match ChainSpec::from(id) {
|
||||||
Some(spec) => Some(spec.load()?),
|
Some(spec) => Some(spec.load()?),
|
||||||
None => None,
|
None => None,
|
||||||
@@ -93,7 +108,7 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
|
|||||||
info!("Roles: {:?}", config.roles);
|
info!("Roles: {:?}", config.roles);
|
||||||
let mut runtime = Runtime::new()?;
|
let mut runtime = Runtime::new()?;
|
||||||
let executor = runtime.executor();
|
let executor = runtime.executor();
|
||||||
match config.roles == service::Roles::LIGHT {
|
match config.roles == ServiceRoles::LIGHT {
|
||||||
true => run_until_exit(&mut runtime, service::Factory::new_light(config, executor)?, exit)?,
|
true => run_until_exit(&mut runtime, service::Factory::new_light(config, executor)?, exit)?,
|
||||||
false => run_until_exit(&mut runtime, service::Factory::new_full(config, executor)?, exit)?,
|
false => run_until_exit(&mut runtime, service::Factory::new_full(config, executor)?, exit)?,
|
||||||
}
|
}
|
||||||
@@ -108,7 +123,7 @@ fn run_until_exit<C, E>(
|
|||||||
e: E,
|
e: E,
|
||||||
) -> error::Result<()>
|
) -> error::Result<()>
|
||||||
where
|
where
|
||||||
C: service::Components,
|
C: substrate_service::Components,
|
||||||
E: IntoExit,
|
E: IntoExit,
|
||||||
{
|
{
|
||||||
let (exit_send, exit) = exit_future::signal();
|
let (exit_send, exit) = exit_future::signal();
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Substrate is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Substrate is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![warn(unused_extern_crates)]
|
||||||
|
|
||||||
|
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use transaction_pool::{self, txpool::{Pool as TransactionPool}};
|
||||||
|
use node_primitives::Block;
|
||||||
|
use node_runtime::GenesisConfig;
|
||||||
|
use node_network::Protocol as DemoProtocol;
|
||||||
|
use substrate_service::{
|
||||||
|
FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
|
||||||
|
LightBackend, FullExecutor, LightExecutor
|
||||||
|
};
|
||||||
|
use network::import_queue::{BasicQueue, BlockOrigin, ImportBlock, Verifier};
|
||||||
|
use runtime_primitives::{traits::Block as BlockT};
|
||||||
|
use primitives::AuthorityId;
|
||||||
|
use node_executor;
|
||||||
|
|
||||||
|
// TODO: Remove me, when we have a functional consensus.
|
||||||
|
/// A verifier that doesn't actually do any checks
|
||||||
|
pub struct NoneVerifier;
|
||||||
|
/// This Verifiyer accepts all data as valid
|
||||||
|
impl<B: BlockT> Verifier<B> for NoneVerifier {
|
||||||
|
fn verify(
|
||||||
|
&self,
|
||||||
|
origin: BlockOrigin,
|
||||||
|
header: B::Header,
|
||||||
|
justification: Vec<u8>,
|
||||||
|
body: Option<Vec<B::Extrinsic>>
|
||||||
|
) -> Result<(ImportBlock<B>, Option<Vec<AuthorityId>>), String> {
|
||||||
|
Ok((ImportBlock {
|
||||||
|
origin,
|
||||||
|
header,
|
||||||
|
body,
|
||||||
|
finalized: true,
|
||||||
|
external_justification: justification,
|
||||||
|
internal_justification: vec![],
|
||||||
|
auxiliary: Vec::new(),
|
||||||
|
}, None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
construct_simple_service!(Service);
|
||||||
|
|
||||||
|
construct_service_factory! {
|
||||||
|
struct Factory {
|
||||||
|
Block = Block,
|
||||||
|
NetworkProtocol = DemoProtocol { |config| Ok(DemoProtocol::new()) },
|
||||||
|
RuntimeDispatch = node_executor::Executor,
|
||||||
|
FullTransactionPoolApi = transaction_pool::ChainApi<FullBackend<Self>, FullExecutor<Self>, Block>
|
||||||
|
{ |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
|
||||||
|
LightTransactionPoolApi = transaction_pool::ChainApi<LightBackend<Self>, LightExecutor<Self>, Block>
|
||||||
|
{ |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
|
||||||
|
Genesis = GenesisConfig,
|
||||||
|
Configuration = (),
|
||||||
|
FullService = Service<FullComponents<Self>>
|
||||||
|
{ |config, executor| Service::<FullComponents<Factory>>::new(config, executor) },
|
||||||
|
LightService = Service<LightComponents<Self>>
|
||||||
|
{ |config, executor| Service::<LightComponents<Factory>>::new(config, executor) },
|
||||||
|
ImportQueue = BasicQueue<Block, NoneVerifier>
|
||||||
|
{ |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) }
|
||||||
|
{ |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[cfg(feature = "rhd")]
|
||||||
|
fn test_sync() {
|
||||||
|
use {service_test, Factory};
|
||||||
|
use client::{ImportBlock, BlockOrigin};
|
||||||
|
|
||||||
|
let alice: Arc<ed25519::Pair> = Arc::new(Keyring::Alice.into());
|
||||||
|
let bob: Arc<ed25519::Pair> = Arc::new(Keyring::Bob.into());
|
||||||
|
let validators = vec![alice.public().0.into(), bob.public().0.into()];
|
||||||
|
let keys: Vec<&ed25519::Pair> = vec![&*alice, &*bob];
|
||||||
|
let offline = Arc::new(RwLock::new(OfflineTracker::new()));
|
||||||
|
let dummy_runtime = ::tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let block_factory = |service: &<Factory as service::ServiceFactory>::FullService| {
|
||||||
|
let block_id = BlockId::number(service.client().info().unwrap().chain.best_number);
|
||||||
|
let parent_header = service.client().header(&block_id).unwrap().unwrap();
|
||||||
|
let consensus_net = ConsensusNetwork::new(service.network(), service.client().clone());
|
||||||
|
let proposer_factory = consensus::ProposerFactory {
|
||||||
|
client: service.client().clone(),
|
||||||
|
transaction_pool: service.transaction_pool().clone(),
|
||||||
|
network: consensus_net,
|
||||||
|
offline: offline.clone(),
|
||||||
|
force_delay: 0,
|
||||||
|
handle: dummy_runtime.executor(),
|
||||||
|
};
|
||||||
|
let (proposer, _, _) = proposer_factory.init(&parent_header, &validators, alice.clone()).unwrap();
|
||||||
|
let block = proposer.propose().expect("Error making test block");
|
||||||
|
ImportBlock {
|
||||||
|
origin: BlockOrigin::File,
|
||||||
|
external_justification: Vec::new(),
|
||||||
|
internal_justification: Vec::new(),
|
||||||
|
finalized: true,
|
||||||
|
body: Some(block.extrinsics),
|
||||||
|
header: block.header,
|
||||||
|
auxiliary: Vec::new(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let extrinsic_factory = |service: &<Factory as service::ServiceFactory>::FullService| {
|
||||||
|
let payload = (0, Call::Balances(BalancesCall::transfer(RawAddress::Id(bob.public().0.into()), 69.into())), Era::immortal(), service.client().genesis_hash());
|
||||||
|
let signature = alice.sign(&payload.encode()).into();
|
||||||
|
let id = alice.public().0.into();
|
||||||
|
let xt = UncheckedExtrinsic {
|
||||||
|
signature: Some((RawAddress::Id(id), signature, payload.0, Era::immortal())),
|
||||||
|
function: payload.1,
|
||||||
|
}.encode();
|
||||||
|
let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
|
||||||
|
OpaqueExtrinsic(v)
|
||||||
|
};
|
||||||
|
service_test::sync::<Factory, _, _>(chain_spec::integration_test_config(), block_factory, extrinsic_factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "node-service"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
error-chain = "0.12"
|
|
||||||
hex-literal = "0.1"
|
|
||||||
lazy_static = "1.0"
|
|
||||||
log = "0.4"
|
|
||||||
node-consensus = { path = "../consensus" }
|
|
||||||
node-executor = { path = "../executor" }
|
|
||||||
node-network = { path = "../network" }
|
|
||||||
node-primitives = { path = "../primitives" }
|
|
||||||
node-runtime = { path = "../runtime" }
|
|
||||||
parity-codec = { version = "2.1" }
|
|
||||||
parking_lot = "0.4"
|
|
||||||
slog = "^2"
|
|
||||||
sr-io = { path = "../../core/sr-io" }
|
|
||||||
sr-primitives = { path = "../../core/sr-primitives" }
|
|
||||||
substrate-client = { path = "../../core/client" }
|
|
||||||
substrate-network = { path = "../../core/network" }
|
|
||||||
substrate-primitives = { path = "../../core/primitives" }
|
|
||||||
substrate-service = { path = "../../core/service" }
|
|
||||||
substrate-telemetry = { path = "../../core/telemetry" }
|
|
||||||
substrate-transaction-pool = { path = "../../core/transaction-pool" }
|
|
||||||
tokio = "0.1.7"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
substrate-service-test = { path = "../../core/service/test" }
|
|
||||||
substrate-test-client = { path = "../../core/test-client" }
|
|
||||||
substrate-keyring = { path = "../../core/keyring" }
|
|
||||||
rhododendron = "0.3"
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Substrate.
|
|
||||||
|
|
||||||
// Substrate is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Substrate is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#![warn(unused_extern_crates)]
|
|
||||||
|
|
||||||
//! Substrate service. Specialized wrapper over substrate service.
|
|
||||||
|
|
||||||
extern crate node_primitives;
|
|
||||||
extern crate node_runtime;
|
|
||||||
extern crate node_executor;
|
|
||||||
extern crate node_network;
|
|
||||||
extern crate substrate_client as client;
|
|
||||||
extern crate substrate_network as network;
|
|
||||||
extern crate substrate_primitives as primitives;
|
|
||||||
extern crate substrate_service as service;
|
|
||||||
extern crate substrate_transaction_pool as transaction_pool;
|
|
||||||
extern crate tokio;
|
|
||||||
#[cfg(test)]
|
|
||||||
extern crate substrate_service_test as service_test;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate hex_literal;
|
|
||||||
#[cfg(all(test, feature="rhd"))]
|
|
||||||
extern crate rhododendron as rhd;
|
|
||||||
extern crate sr_primitives as runtime_primitives;
|
|
||||||
pub mod chain_spec;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use transaction_pool::txpool::{Pool as TransactionPool};
|
|
||||||
use node_primitives::{Block, Hash};
|
|
||||||
use node_runtime::GenesisConfig;
|
|
||||||
use client::Client;
|
|
||||||
use node_network::Protocol as DemoProtocol;
|
|
||||||
use tokio::runtime::TaskExecutor;
|
|
||||||
use service::FactoryFullConfiguration;
|
|
||||||
use network::import_queue::{BasicQueue, BlockOrigin, ImportBlock, Verifier};
|
|
||||||
use runtime_primitives::{traits::Block as BlockT};
|
|
||||||
use primitives::{Blake2Hasher, AuthorityId};
|
|
||||||
|
|
||||||
pub use service::{Roles, PruningMode, TransactionPoolOptions, ServiceFactory,
|
|
||||||
ErrorKind, Error, ComponentBlock, LightComponents, FullComponents};
|
|
||||||
pub use client::ExecutionStrategy;
|
|
||||||
|
|
||||||
/// Specialised `ChainSpec`.
|
|
||||||
pub type ChainSpec = service::ChainSpec<GenesisConfig>;
|
|
||||||
/// Client type for specialised `Components`.
|
|
||||||
pub type ComponentClient<C> = Client<<C as Components>::Backend, <C as Components>::Executor, Block>;
|
|
||||||
pub type NetworkService = network::Service<Block, <Factory as service::ServiceFactory>::NetworkProtocol, Hash>;
|
|
||||||
|
|
||||||
/// A verifier that doesn't actually do any checks
|
|
||||||
pub struct NoneVerifier;
|
|
||||||
/// This Verifiyer accepts all data as valid
|
|
||||||
impl<B: BlockT> Verifier<B> for NoneVerifier {
|
|
||||||
fn verify(
|
|
||||||
&self,
|
|
||||||
origin: BlockOrigin,
|
|
||||||
header: B::Header,
|
|
||||||
justification: Vec<u8>,
|
|
||||||
body: Option<Vec<B::Extrinsic>>
|
|
||||||
) -> Result<(ImportBlock<B>, Option<Vec<AuthorityId>>), String> {
|
|
||||||
Ok((ImportBlock {
|
|
||||||
origin,
|
|
||||||
header,
|
|
||||||
body,
|
|
||||||
finalized: true,
|
|
||||||
external_justification: justification,
|
|
||||||
internal_justification: vec![],
|
|
||||||
auxiliary: Vec::new(),
|
|
||||||
}, None))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A collection of type to generalise specific components over full / light client.
|
|
||||||
pub trait Components: service::Components {
|
|
||||||
/// Demo API.
|
|
||||||
type Api: 'static + Send + Sync;
|
|
||||||
/// Client backend.
|
|
||||||
type Backend: 'static + client::backend::Backend<Block, Blake2Hasher>;
|
|
||||||
/// Client executor.
|
|
||||||
type Executor: 'static + client::CallExecutor<Block, Blake2Hasher> + Send + Sync;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Components for service::LightComponents<Factory> {
|
|
||||||
type Api = service::LightClient<Factory>;
|
|
||||||
type Executor = service::LightExecutor<Factory>;
|
|
||||||
type Backend = service::LightBackend<Factory>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Components for service::FullComponents<Factory> {
|
|
||||||
type Api = service::FullClient<Factory>;
|
|
||||||
type Executor = service::FullExecutor<Factory>;
|
|
||||||
type Backend = service::FullBackend<Factory>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// All configuration for the node.
|
|
||||||
pub type Configuration = FactoryFullConfiguration<Factory>;
|
|
||||||
|
|
||||||
/// Demo-specific configuration.
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct CustomConfiguration;
|
|
||||||
|
|
||||||
/// Config for the substrate service.
|
|
||||||
pub struct Factory;
|
|
||||||
|
|
||||||
impl service::ServiceFactory for Factory {
|
|
||||||
type Block = Block;
|
|
||||||
type ExtrinsicHash = Hash;
|
|
||||||
type NetworkProtocol = DemoProtocol;
|
|
||||||
type RuntimeDispatch = node_executor::Executor;
|
|
||||||
type FullTransactionPoolApi = transaction_pool::ChainApi<service::FullBackend<Self>, service::FullExecutor<Self>, Block>;
|
|
||||||
type LightTransactionPoolApi = transaction_pool::ChainApi<service::LightBackend<Self>, service::LightExecutor<Self>, Block>;
|
|
||||||
type Genesis = GenesisConfig;
|
|
||||||
type Configuration = CustomConfiguration;
|
|
||||||
type FullService = Service<service::FullComponents<Self>>;
|
|
||||||
type LightService = Service<service::LightComponents<Self>>;
|
|
||||||
/// instance of import queue for clients
|
|
||||||
type ImportQueue = BasicQueue<Block, NoneVerifier>;
|
|
||||||
|
|
||||||
fn build_full_transaction_pool(config: TransactionPoolOptions, client: Arc<service::FullClient<Self>>)
|
|
||||||
-> Result<TransactionPool<Self::FullTransactionPoolApi>, Error>
|
|
||||||
{
|
|
||||||
Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_light_transaction_pool(config: TransactionPoolOptions, client: Arc<service::LightClient<Self>>)
|
|
||||||
-> Result<TransactionPool<Self::LightTransactionPoolApi>, Error>
|
|
||||||
{
|
|
||||||
Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_network_protocol(_config: &Configuration)
|
|
||||||
-> Result<DemoProtocol, Error>
|
|
||||||
{
|
|
||||||
Ok(DemoProtocol::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_full_import_queue(
|
|
||||||
_config: &FactoryFullConfiguration<Self>,
|
|
||||||
_client: Arc<service::FullClient<Self>>,
|
|
||||||
) -> Result<BasicQueue<Block, NoneVerifier>, service::Error> {
|
|
||||||
Ok(BasicQueue::new(Arc::new(NoneVerifier {})))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_light_import_queue(
|
|
||||||
_config: &FactoryFullConfiguration<Self>,
|
|
||||||
_client: Arc<service::LightClient<Self>>,
|
|
||||||
) -> Result<BasicQueue<Block, NoneVerifier>, service::Error> {
|
|
||||||
Ok(BasicQueue::new(Arc::new(NoneVerifier {})))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_light(config: Configuration, executor: TaskExecutor)
|
|
||||||
-> Result<Service<LightComponents<Factory>>, Error>
|
|
||||||
{
|
|
||||||
let service = service::Service::<LightComponents<Factory>>::new(config, executor.clone())?;
|
|
||||||
Ok(Service {
|
|
||||||
inner: service,
|
|
||||||
_consensus: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_full(config: Configuration, executor: TaskExecutor)
|
|
||||||
-> Result<Service<FullComponents<Factory>>, Error>
|
|
||||||
{
|
|
||||||
let service = service::Service::<FullComponents<Factory>>::new(config, executor.clone())?;
|
|
||||||
// FIXME: Spin consensus service if configured
|
|
||||||
let consensus = None;
|
|
||||||
Ok(Service {
|
|
||||||
inner: service,
|
|
||||||
_consensus: consensus,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Demo service.
|
|
||||||
pub struct Service<C: Components> {
|
|
||||||
inner: service::Service<C>,
|
|
||||||
_consensus: Option<bool>, // FIXME: add actual consensus engine
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Components> ::std::ops::Deref for Service<C> {
|
|
||||||
type Target = service::Service<C>;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Creates bare client without any networking.
|
|
||||||
pub fn new_client(config: Configuration)
|
|
||||||
-> Result<Arc<service::ComponentClient<FullComponents<Factory>>>, Error>
|
|
||||||
{
|
|
||||||
service::new_client::<Factory>(&config)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use {service_test, Factory, chain_spec};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_connectivity() {
|
|
||||||
service_test::connectivity::<Factory>(chain_spec::integration_test_config());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(feature = "rhd")]
|
|
||||||
fn test_sync() {
|
|
||||||
use client::{ImportBlock, BlockOrigin};
|
|
||||||
|
|
||||||
let alice: Arc<ed25519::Pair> = Arc::new(Keyring::Alice.into());
|
|
||||||
let bob: Arc<ed25519::Pair> = Arc::new(Keyring::Bob.into());
|
|
||||||
let validators = vec![alice.public().0.into(), bob.public().0.into()];
|
|
||||||
let keys: Vec<&ed25519::Pair> = vec![&*alice, &*bob];
|
|
||||||
let offline = Arc::new(RwLock::new(OfflineTracker::new()));
|
|
||||||
let dummy_runtime = ::tokio::runtime::Runtime::new().unwrap();
|
|
||||||
let block_factory = |service: &<Factory as service::ServiceFactory>::FullService| {
|
|
||||||
let block_id = BlockId::number(service.client().info().unwrap().chain.best_number);
|
|
||||||
let parent_header = service.client().header(&block_id).unwrap().unwrap();
|
|
||||||
let consensus_net = ConsensusNetwork::new(service.network(), service.client().clone());
|
|
||||||
let proposer_factory = consensus::ProposerFactory {
|
|
||||||
client: service.client().clone(),
|
|
||||||
transaction_pool: service.transaction_pool().clone(),
|
|
||||||
network: consensus_net,
|
|
||||||
offline: offline.clone(),
|
|
||||||
force_delay: 0,
|
|
||||||
handle: dummy_runtime.executor(),
|
|
||||||
};
|
|
||||||
let (proposer, _, _) = proposer_factory.init(&parent_header, &validators, alice.clone()).unwrap();
|
|
||||||
let block = proposer.propose().expect("Error making test block");
|
|
||||||
ImportBlock {
|
|
||||||
origin: BlockOrigin::File,
|
|
||||||
external_justification: Vec::new(),
|
|
||||||
internal_justification: Vec::new(),
|
|
||||||
finalized: true,
|
|
||||||
body: Some(block.extrinsics),
|
|
||||||
header: block.header,
|
|
||||||
auxiliary: Vec::new(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let extrinsic_factory = |service: &<Factory as service::ServiceFactory>::FullService| {
|
|
||||||
let payload = (0, Call::Balances(BalancesCall::transfer(RawAddress::Id(bob.public().0.into()), 69.into())), Era::immortal(), service.client().genesis_hash());
|
|
||||||
let signature = alice.sign(&payload.encode()).into();
|
|
||||||
let id = alice.public().0.into();
|
|
||||||
let xt = UncheckedExtrinsic {
|
|
||||||
signature: Some((RawAddress::Id(id), signature, payload.0, Era::immortal())),
|
|
||||||
function: payload.1,
|
|
||||||
}.encode();
|
|
||||||
let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
|
|
||||||
OpaqueExtrinsic(v)
|
|
||||||
};
|
|
||||||
service_test::sync::<Factory, _, _>(chain_spec::integration_test_config(), block_factory, extrinsic_factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user