mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 07:01:05 +00:00
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 10064461570436465ed664 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 100644139cef13f90dbf3d M core/client/src/error.rs :100644 100644 2800c503 3298e66a M core/client/src/runtime_api.rs :100644 100644affa1c5c809b08bc M core/primitives/src/lib.rs :100644 1006442877dfa9d5547413 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 1006442e113ab6dcc01a6d M srml/metadata/Cargo.toml :100644 100644ea722a700809531aM 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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user