Implement runtime api client side directly in the runtime (#1094)

* Move `initialise_block` into `Core` trait as it is crucial calling the API functions

* Switch to first version of new runtime API implementation

* Fixes bug in tests

* Reenable asserts

* Directly use the `TestAPI` in the tests

* Start improving the api traits

:100644 100644 898aadc7 49217199 M	Cargo.lock
:100644 100644 61570436 465ed664 M	core/client/src/backend.rs
:100644 100644 5d0c886b 64d710fd M	core/client/src/block_builder.rs
:100644 100644 c447855e 5ecbe474 M	core/client/src/client.rs
:100644 100644 139cef13 f90dbf3d M	core/client/src/error.rs
:100644 100644 2800c503 3298e66a M	core/client/src/runtime_api.rs
:100644 100644 affa1c5c 809b08bc M	core/primitives/src/lib.rs
:100644 100644 2877dfa9 d5547413 M	core/sr-api/Cargo.toml
:100644 100644 9a49784d 6a625a03 M	core/sr-api/src/lib.rs
:100644 100644 7c28e1c7 a1a444a9 M	core/sr-primitives/src/traits.rs
:100644 100644 2e113ab6 dcc01a6d M	srml/metadata/Cargo.toml
:100644 100644 ea722a70 0809531a M	srml/metadata/src/lib.rs

* Refactoring

* Move `sr-api` into client and more refactoring

* Fixes tests

* Some documentation and cleanup

* Fixes compilation after rebase

* More refactoring and more documentation

* Makes `substrate-client` compilable on `wasm`

On `wasm` it basically just exports the runtime api stuff.

* Fixes grumbles

* Updates wasm files after rebasing the master

* Remove TODO comment

* Remove whitespaces

* Fixes after rebasing master

* Another rebase, another fix commit
This commit is contained in:
Bastian Köcher
2018-11-13 13:33:28 +01:00
committed by Gav Wood
parent 6e3c56c135
commit 9063d1acae
51 changed files with 2993 additions and 777 deletions
+186 -22
View File
@@ -16,21 +16,20 @@
//! Substrate service components.
use std::sync::Arc;
use std::marker::PhantomData;
use std::ops::Deref;
use std::{sync::Arc, net::SocketAddr, marker::PhantomData, ops::Deref};
use serde::{Serialize, de::DeserializeOwned};
use tokio::runtime::TaskExecutor;
use chain_spec::ChainSpec;
use chain_spec::{ChainSpec, Properties};
use client_db;
use client::{self, Client};
use {error, Service};
use client::{self, Client, runtime_api::{TaggedTransactionQueue, Metadata}};
use {error, Service, RpcConfig, maybe_start_server, TransactionPoolAdapter};
use network::{self, OnDemand, import_queue::ImportQueue};
use substrate_executor::{NativeExecutor, NativeExecutionDispatch};
use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool};
use runtime_primitives::{traits::Block as BlockT, traits::Header as HeaderT, BuildStorage};
use runtime_primitives::{traits::Block as BlockT, traits::Header as HeaderT, BuildStorage, generic::SignedBlock};
use config::Configuration;
use primitives::{H256, Blake2Hasher};
use primitives::{Blake2Hasher, H256};
use rpc;
// Type aliases.
// These exist mainly to avoid typing `<F as Factory>::Foo` all over the code.
@@ -70,10 +69,10 @@ pub type LightExecutor<F> = client::light::call_executor::RemoteCallExecutor<
>;
/// Full client type for a factory.
pub type FullClient<F> = Client<FullBackend<F>, FullExecutor<F>, <F as ServiceFactory>::Block>;
pub type FullClient<F> = Client<FullBackend<F>, FullExecutor<F>, <F as ServiceFactory>::Block, <F as ServiceFactory>::RuntimeApi>;
/// Light client type for a factory.
pub type LightClient<F> = Client<LightBackend<F>, LightExecutor<F>, <F as ServiceFactory>::Block>;
pub type LightClient<F> = Client<LightBackend<F>, LightExecutor<F>, <F as ServiceFactory>::Block, <F as ServiceFactory>::RuntimeApi>;
/// `ChainSpec` specialization for a factory.
pub type FactoryChainSpec<F> = ChainSpec<<F as ServiceFactory>::Genesis>;
@@ -97,7 +96,8 @@ pub type FactoryFullConfiguration<F> = Configuration<<F as ServiceFactory>::Conf
pub type ComponentClient<C> = Client<
<C as Components>::Backend,
<C as Components>::Executor,
FactoryBlock<<C as Components>::Factory>
FactoryBlock<<C as Components>::Factory>,
<C as Components>::RuntimeApi,
>;
/// Block type for `Components`
@@ -116,10 +116,114 @@ pub type PoolApi<C> = <C as Components>::TransactionPoolApi;
pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {}
impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
/// Something that can start the RPC service.
pub trait StartRPC<C: Components> {
fn start_rpc(
client: Arc<Client<C::Backend, C::Executor, ComponentBlock<C>, C::RuntimeApi>>,
chain_name: String,
impl_name: &'static str,
impl_version: &'static str,
rpc_http: Option<SocketAddr>,
rpc_ws: Option<SocketAddr>,
properties: Properties,
task_executor: TaskExecutor,
transaction_pool: Arc<TransactionPool<C::TransactionPoolApi>>,
) -> Result<(Option<rpc::HttpServer>, Option<rpc::WsServer>), error::Error>;
}
impl<T: Components> StartRPC<Self> for T where
T::RuntimeApi: Metadata<ComponentBlock<T>>,
for<'de> SignedBlock<ComponentBlock<T>>: ::serde::Deserialize<'de>,
{
fn start_rpc(
client: Arc<Client<T::Backend, T::Executor, ComponentBlock<T>, T::RuntimeApi>>,
chain_name: String,
impl_name: &'static str,
impl_version: &'static str,
rpc_http: Option<SocketAddr>,
rpc_ws: Option<SocketAddr>,
properties: Properties,
task_executor: TaskExecutor,
transaction_pool: Arc<TransactionPool<T::TransactionPoolApi>>,
) -> Result<(Option<rpc::HttpServer>, Option<rpc::WsServer>), error::Error> {
let rpc_config = RpcConfig { properties, chain_name, impl_name, impl_version };
let handler = || {
let client = client.clone();
let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone());
let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone());
let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone());
let author = rpc::apis::author::Author::new(
client.clone(), transaction_pool.clone(), subscriptions
);
rpc::rpc_handler::<ComponentBlock<T>, ComponentExHash<T>, _, _, _, _>(
state,
chain,
author,
rpc_config.clone(),
)
};
Ok((
maybe_start_server(rpc_http, |address| rpc::start_http(address, handler()))?,
maybe_start_server(rpc_ws, |address| rpc::start_ws(address, handler()))?,
))
}
}
/// Something that can create an instance of `network::Params`.
pub trait CreateNetworkParams<C: Components> {
fn create_network_params<S>(
client: Arc<Client<C::Backend, C::Executor, ComponentBlock<C>, C::RuntimeApi>>,
roles: network::Roles,
network_config: network::NetworkConfiguration,
on_demand: Option<Arc<OnDemand<FactoryBlock<C::Factory>, NetworkService<C::Factory>>>>,
transaction_pool_adapter: TransactionPoolAdapter<C>,
specialization: S,
) -> network::Params<ComponentBlock<C>, S, ComponentExHash<C>>;
}
impl<T: Components> CreateNetworkParams<Self> for T where
T::RuntimeApi: TaggedTransactionQueue<ComponentBlock<T>>
{
fn create_network_params<S>(
client: Arc<Client<T::Backend, T::Executor, ComponentBlock<T>, T::RuntimeApi>>,
roles: network::Roles,
network_config: network::NetworkConfiguration,
on_demand: Option<Arc<OnDemand<FactoryBlock<T::Factory>, NetworkService<T::Factory>>>>,
transaction_pool_adapter: TransactionPoolAdapter<T>,
specialization: S,
) -> network::Params<ComponentBlock<T>, S, ComponentExHash<T>> {
network::Params {
config: network::ProtocolConfig { roles },
network_config,
chain: client,
on_demand: on_demand.map(|d| d as Arc<network::OnDemandService<ComponentBlock<T>>>),
transaction_pool: Arc::new(transaction_pool_adapter),
specialization,
}
}
}
/// The super trait that combines all required traits a `Service` needs to implement.
pub trait ServiceTrait<C: Components>:
Deref<Target = Service<C>>
+ Send
+ Sync
+ 'static
+ StartRPC<C>
+ CreateNetworkParams<C>
{}
impl<C: Components, T> ServiceTrait<C> for T where
T: Deref<Target = Service<C>> + Send + Sync + 'static + StartRPC<C> + CreateNetworkParams<C>
{}
/// A collection of types and methods to build a service on top of the substrate service.
pub trait ServiceFactory: 'static + Sized {
/// Block type.
type Block: BlockT<Hash=H256>;
/// The type that implements the runtime API.
type RuntimeApi: Send + Sync;
/// Network protocol extensions.
type NetworkProtocol: network::specialization::Specialization<Self::Block>;
/// Chain runtime.
@@ -133,9 +237,9 @@ pub trait ServiceFactory: 'static + Sized {
/// Other configuration for service members.
type Configuration: Default;
/// Extended full service type.
type FullService: Deref<Target = Service<FullComponents<Self>>> + Send + Sync + 'static;
type FullService: ServiceTrait<FullComponents<Self>>;
/// Extended light service type.
type LightService: Deref<Target = Service<LightComponents<Self>>> + Send + Sync + 'static;
type LightService: ServiceTrait<LightComponents<Self>>;
/// ImportQueue for full client
type FullImportQueue: network::import_queue::ImportQueue<Self::Block> + 'static;
/// ImportQueue for light clients
@@ -192,7 +296,7 @@ pub trait ServiceFactory: 'static + Sized {
}
/// A collection of types and function to generalise over full / light client type.
pub trait Components: 'static {
pub trait Components: Sized + 'static {
/// Associated service factory.
type Factory: ServiceFactory;
/// Client backend.
@@ -204,6 +308,12 @@ pub trait Components: 'static {
Hash = <<Self::Factory as ServiceFactory>::Block as BlockT>::Hash,
Block = FactoryBlock<Self::Factory>
>;
/// The type that implements the runtime API.
type RuntimeApi: Send + Sync;
/// A type that can start the RPC.
type RPC: StartRPC<Self>;
/// A type that can create the network params.
type CreateNetworkParams: CreateNetworkParams<Self>;
/// Our Import Queue
type ImportQueue: ImportQueue<FactoryBlock<Self::Factory>> + 'static;
@@ -212,11 +322,13 @@ pub trait Components: 'static {
fn build_client(
config: &FactoryFullConfiguration<Self::Factory>,
executor: CodeExecutor<Self::Factory>,
)
-> Result<(
) -> Result<
(
Arc<ComponentClient<Self>>,
Option<Arc<OnDemand<FactoryBlock<Self::Factory>, NetworkService<Self::Factory>>>>
), error::Error>;
),
error::Error
>;
/// Create extrinsic pool.
fn build_transaction_pool(config: TransactionPoolOptions, client: Arc<ComponentClient<Self>>)
@@ -232,6 +344,29 @@ pub trait Components: 'static {
/// A struct that implement `Components` for the full client.
pub struct FullComponents<Factory: ServiceFactory> {
_factory: PhantomData<Factory>,
service: Service<FullComponents<Factory>>,
}
impl<Factory: ServiceFactory> FullComponents<Factory> {
pub fn new(
config: FactoryFullConfiguration<Factory>,
task_executor: TaskExecutor
) -> Result<Self, error::Error> {
Ok(
Self {
_factory: Default::default(),
service: Service::new(config, task_executor)?,
}
)
}
}
impl<Factory: ServiceFactory> Deref for FullComponents<Factory> {
type Target = Service<Self>;
fn deref(&self) -> &Self::Target {
&self.service
}
}
impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
@@ -240,6 +375,9 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
type Backend = FullBackend<Factory>;
type TransactionPoolApi = <Factory as ServiceFactory>::FullTransactionPoolApi;
type ImportQueue = Factory::FullImportQueue;
type RuntimeApi = Factory::RuntimeApi;
type RPC = Factory::FullService;
type CreateNetworkParams = Factory::FullService;
fn build_client(
config: &FactoryFullConfiguration<Factory>,
@@ -281,6 +419,29 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
/// A struct that implement `Components` for the light client.
pub struct LightComponents<Factory: ServiceFactory> {
_factory: PhantomData<Factory>,
service: Service<LightComponents<Factory>>,
}
impl<Factory: ServiceFactory> LightComponents<Factory> {
pub fn new(
config: FactoryFullConfiguration<Factory>,
task_executor: TaskExecutor
) -> Result<Self, error::Error> {
Ok(
Self {
_factory: Default::default(),
service: Service::new(config, task_executor)?,
}
)
}
}
impl<Factory: ServiceFactory> Deref for LightComponents<Factory> {
type Target = Service<Self>;
fn deref(&self) -> &Self::Target {
&self.service
}
}
impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
@@ -289,16 +450,19 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
type Backend = LightBackend<Factory>;
type TransactionPoolApi = <Factory as ServiceFactory>::LightTransactionPoolApi;
type ImportQueue = <Factory as ServiceFactory>::LightImportQueue;
type RuntimeApi = Factory::RuntimeApi;
type RPC = Factory::LightService;
type CreateNetworkParams = Factory::LightService;
fn build_client(
config: &FactoryFullConfiguration<Factory>,
executor: CodeExecutor<Self::Factory>,
)
-> Result<(
Arc<ComponentClient<Self>>,
Option<Arc<OnDemand<FactoryBlock<Self::Factory>,
NetworkService<Self::Factory>>>>
), error::Error>
-> Result<
(
Arc<ComponentClient<Self>>,
Option<Arc<OnDemand<FactoryBlock<Self::Factory>, NetworkService<Self::Factory>>>>
), error::Error>
{
let db_settings = client_db::DatabaseSettings {
cache_size: None,
+23 -24
View File
@@ -23,11 +23,11 @@ use std::time::{self, Duration, Instant};
use std;
use client::{self, error, Client as SubstrateClient, CallExecutor};
use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, id::BLOCK_BUILDER};
use client::{block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::{id::BLOCK_BUILDER, Core}};
use codec::{Decode, Encode};
use consensus_common::{self, InherentData, evaluation, offline_tracker::OfflineTracker};
use primitives::{H256, AuthorityId, ed25519, Blake2Hasher};
use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT};
use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi};
use runtime_primitives::generic::BlockId;
use transaction_pool::txpool::{self, Pool as TransactionPool};
@@ -47,11 +47,8 @@ pub trait BlockBuilder<Block: BlockT> {
}
/// Local client abstraction for the consensus.
pub trait AuthoringApi:
Send
+ Sync
+ BlockBuilderAPI<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
+ Core<<Self as AuthoringApi>::Block, AuthorityId, Error=<Self as AuthoringApi>::Error>
pub trait AuthoringApi: Send + Sync + ProvideRuntimeApi where
<Self as ProvideRuntimeApi>::Api: Core<Self::Block>
{
/// The block used for this API type.
type Block: BlockT;
@@ -67,20 +64,22 @@ pub trait AuthoringApi:
) -> Result<Self::Block, error::Error>;
}
impl<'a, B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where
B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
impl<'a, B, E, Block, RA> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, Block, SubstrateClient<B, E, Block, RA>> where
B: client::backend::Backend<Block, Blake2Hasher> + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
RA: BlockBuilderApi<Block>,
{
fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<(), error::Error> {
client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into)
}
}
impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
impl<B, E, Block, RA> AuthoringApi for SubstrateClient<B, E, Block, RA> where
B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
RA: BlockBuilderApi<Block>,
{
type Block = Block;
type Error = client::error::Error;
@@ -95,7 +94,7 @@ impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
let mut block_builder = self.new_block_at(at)?;
if runtime_version.has_api(BLOCK_BUILDER, 1) {
self.inherent_extrinsics(at, &inherent_data)?
self.runtime_api().inherent_extrinsics(at, &inherent_data)?
.into_iter().try_for_each(|i| block_builder.push(i))?;
}
@@ -106,10 +105,7 @@ impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
}
/// Proposer factory.
pub struct ProposerFactory<C, A> where
C: AuthoringApi,
A: txpool::ChainApi,
{
pub struct ProposerFactory<C, A> where A: txpool::ChainApi {
/// The client instance.
pub client: Arc<C>,
/// The transaction pool.
@@ -122,10 +118,11 @@ pub struct ProposerFactory<C, A> where
impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for ProposerFactory<C, A> where
C: AuthoringApi,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<<C as AuthoringApi>::Block>,
A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
client::error::Error: From<<C as AuthoringApi>::Error>
{
type Proposer = Proposer<C, A>;
type Proposer = Proposer<<C as AuthoringApi>::Block, C, A>;
type Error = error::Error;
fn init(
@@ -138,7 +135,7 @@ impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for Propose
let id = BlockId::hash(parent_hash);
let authorities: Vec<AuthorityId> = self.client.authorities(&id)?;
let authorities: Vec<AuthorityId> = self.client.runtime_api().authorities(&id)?;
self.offline.write().note_new_block(&authorities[..]);
info!("Starting consensus session on top of parent {:?}", parent_hash);
@@ -161,21 +158,23 @@ impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for Propose
}
/// The proposer logic.
pub struct Proposer<C: AuthoringApi, A: txpool::ChainApi> {
pub struct Proposer<Block: BlockT, C, A: txpool::ChainApi> {
client: Arc<C>,
start: Instant,
parent_hash: <<C as AuthoringApi>::Block as BlockT>::Hash,
parent_id: BlockId<<C as AuthoringApi>::Block>,
parent_number: <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Number,
parent_hash: <Block as BlockT>::Hash,
parent_id: BlockId<Block>,
parent_number: <<Block as BlockT>::Header as HeaderT>::Number,
transaction_pool: Arc<TransactionPool<A>>,
offline: SharedOfflineTracker,
authorities: Vec<AuthorityId>,
minimum_timestamp: u64,
}
impl<C, A> consensus_common::Proposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
C: AuthoringApi,
A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
impl<Block, C, A> consensus_common::Proposer<<C as AuthoringApi>::Block> for Proposer<Block, C, A> where
Block: BlockT,
C: AuthoringApi<Block=Block>,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<Block>,
A: txpool::ChainApi<Block=Block>,
client::error::Error: From<<C as AuthoringApi>::Error>
{
type Create = Result<<C as AuthoringApi>::Block, error::Error>;
+20 -79
View File
@@ -67,7 +67,7 @@ use parking_lot::{Mutex, RwLock};
use keystore::Store as Keystore;
use client::BlockchainEvents;
use runtime_primitives::traits::{Header, As};
use runtime_primitives::generic::{BlockId, SignedBlock};
use runtime_primitives::generic::BlockId;
use exit_future::Signal;
#[doc(hidden)]
pub use tokio::runtime::TaskExecutor;
@@ -87,8 +87,11 @@ pub use components::{ServiceFactory, FullBackend, FullExecutor, LightBackend,
ComponentBlock, FullClient, LightClient, FullComponents, LightComponents,
CodeExecutor, NetworkService, FactoryChainSpec, FactoryBlock,
FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis,
ComponentExHash, ComponentExtrinsic, FactoryExtrinsic,
ComponentExHash, ComponentExtrinsic, FactoryExtrinsic
};
use components::{StartRPC, CreateNetworkParams};
#[doc(hidden)]
pub use network::OnDemand;
const DEFAULT_PROTOCOL_ID: &'static str = "sup";
@@ -122,7 +125,7 @@ impl<Components> Service<Components>
where
Components: components::Components,
<Components as components::Components>::Executor: std::clone::Clone,
for<'de> SignedBlock<ComponentBlock<Components>>: ::serde::Deserialize<'de>,
// <Components as components::Components>::RuntimeApi: client::runtime_api::BlockBuilder<<<Components as components::Components>::Factory as ServiceFactory>::Block, Error=client::error::Error, OverlayedChanges=client::runtime_api::OverlayedChanges> + Sync + Send + client::runtime_api::Core<<<Components as components::Components>::Factory as components::ServiceFactory>::Block, primitives::AuthorityId, Error=client::error::Error, OverlayedChanges=client::runtime_api::OverlayedChanges> + client::runtime_api::ConstructRuntimeApi<Block=<<Components as components::Components>::Factory as ServiceFactory>::Block> + client::runtime_api::Metadata<<<Components as components::Components>::Factory as components::ServiceFactory>::Block, Vec<u8>, Error=client::error::Error> + client::runtime_api::TaggedTransactionQueue<<<Components as components::Components>::Factory as components::ServiceFactory>::Block, Error=client::error::Error>,
{
/// Creates a new service.
pub fn new(
@@ -173,17 +176,10 @@ impl<Components> Service<Components>
client: client.clone(),
};
let network_params = network::Params {
config: network::ProtocolConfig {
roles: config.roles,
},
network_config: config.network,
chain: client.clone(),
on_demand: on_demand.clone()
.map(|d| d as Arc<network::OnDemandService<ComponentBlock<Components>>>),
transaction_pool: Arc::new(transaction_pool_adapter),
specialization: network_protocol,
};
let network_params = Components::CreateNetworkParams::create_network_params(
client.clone(), config.roles, config.network, on_demand.clone(),
transaction_pool_adapter, network_protocol
);
let mut protocol_id = network::ProtocolId::default();
let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes();
@@ -232,33 +228,13 @@ impl<Components> Service<Components>
task_executor.spawn(events);
}
// RPC
let rpc_config = RpcConfig {
chain_name: config.chain_spec.name().to_string(),
properties: config.chain_spec.properties().clone(),
impl_name: config.impl_name,
impl_version: config.impl_version,
};
let (rpc_http, rpc_ws) = {
let handler = || {
let client = client.clone();
let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone());
let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone());
let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone());
let author = rpc::apis::author::Author::new(client.clone(), transaction_pool.clone(), subscriptions.clone());
rpc::rpc_handler::<ComponentBlock<Components>, ComponentExHash<Components>, _, _, _, _>(
state,
chain,
author,
rpc_config.clone(),
)
};
(
maybe_start_server(config.rpc_http, |address| rpc::start_http(address, handler()))?,
maybe_start_server(config.rpc_ws, |address| rpc::start_ws(address, handler()))?,
)
};
// RPC
let (rpc_http, rpc_ws) = Components::RPC::start_rpc(
client.clone(), config.chain_spec.name().to_string(), config.impl_name,
config.impl_version, config.rpc_http, config.rpc_ws, config.chain_spec.properties(),
task_executor.clone(), transaction_pool.clone()
)?;
let proposer = Arc::new(ProposerFactory {
client: client.clone(),
@@ -309,9 +285,7 @@ impl<Components> Service<Components>
}
}
impl<Components> Service<Components> where
Components: components::Components,
{
impl<Components> Service<Components> where Components: components::Components {
/// Get shared client instance.
pub fn client(&self) -> Arc<ComponentClient<Components>> {
self.client.clone()
@@ -420,7 +394,7 @@ impl<C: Components> TransactionPoolAdapter<C> {
}
}
impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<C>> for TransactionPoolAdapter<C> {
impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<C>> for TransactionPoolAdapter<C> where <C as components::Components>::RuntimeApi: Send + Sync{
fn transactions(&self) -> Vec<(ComponentExHash<C>, ComponentExtrinsic<C>)> {
self.pool.ready()
.map(|t| {
@@ -468,41 +442,6 @@ impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<
}
}
/// 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::Arc<$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::Arc::new($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.
@@ -544,6 +483,7 @@ macro_rules! construct_service_factory {
$(#[$attr:meta])*
struct $name:ident {
Block = $block:ty,
RuntimeApi = $runtime_api:ty,
NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* },
RuntimeDispatch = $dispatch:ty,
FullTransactionPoolApi = $full_transaction:ty { $( $full_transaction_init:tt )* },
@@ -564,6 +504,7 @@ macro_rules! construct_service_factory {
#[allow(unused_variables)]
impl $crate::ServiceFactory for $name {
type Block = $block;
type RuntimeApi = $runtime_api;
type NetworkProtocol = $protocol;
type RuntimeDispatch = $dispatch;
type FullTransactionPoolApi = $full_transaction;