Custom RPC implementation for node. (#3109)

* Allow RPCs to be customized.

* Implement node-rpc extensions.

* Working on a test.

* Add node-testing crate.

* Fix genesis test config

* Fix nonce lookups.

* Clean up.

* Fix expected block type.

* Make the RPC extension function optional.

* Fix service doc test.

* Bump jsonrpc.

* Bump client version.

* Update Cargo.lock

* Update jsonrpc.

* Fix build.

* Remove unused imports.

* Fix signed extra.

* Post merge clean up.

* Fix tests.

* Patch hashmap-core.

* Fix build.

* Fix build.

* Remove hashmap_core patches.
This commit is contained in:
Tomasz Drwięga
2019-08-20 11:06:35 +02:00
committed by Gavin Wood
parent 95abffc8e4
commit 56296386ab
29 changed files with 838 additions and 278 deletions
+68 -21
View File
@@ -34,7 +34,7 @@ use sr_primitives::{
};
use crate::config::Configuration;
use primitives::{Blake2Hasher, H256, traits::BareCryptoStorePtr};
use rpc::{self, apis::system::SystemInfo};
use rpc::{self, system::SystemInfo};
use futures::{prelude::*, future::Executor};
use futures03::{FutureExt as _, channel::mpsc, compat::Compat};
@@ -145,6 +145,9 @@ pub type PoolApi<C> = <C as Components>::TransactionPoolApi;
pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {}
impl<T: Serialize + DeserializeOwned + BuildStorage> RuntimeGenesis for T {}
/// A transport-agnostic handler of the RPC queries.
pub type RpcHandler = rpc_servers::RpcHandler<rpc::Metadata>;
/// Something that can create and store initial session keys from given seeds.
pub trait InitialSessionKeys<C: Components> {
/// Generate the initial session keys for the given seeds and store them in
@@ -168,46 +171,51 @@ impl<C: Components> InitialSessionKeys<Self> for C where
}
/// Something that can start the RPC service.
pub trait StartRPC<C: Components> {
pub trait StartRpc<C: Components> {
fn start_rpc(
client: Arc<ComponentClient<C>>,
system_send_back: mpsc::UnboundedSender<rpc::apis::system::Request<ComponentBlock<C>>>,
system_send_back: mpsc::UnboundedSender<rpc::system::Request<ComponentBlock<C>>>,
system_info: SystemInfo,
task_executor: TaskExecutor,
transaction_pool: Arc<TransactionPool<C::TransactionPoolApi>>,
rpc_extensions: impl rpc::RpcExtension<rpc::Metadata>,
keystore: KeyStorePtr,
) -> rpc::RpcHandler;
) -> RpcHandler;
}
impl<C: Components> StartRPC<Self> for C where
impl<C: Components> StartRpc<C> for C where
ComponentClient<C>: ProvideRuntimeApi,
<ComponentClient<C> as ProvideRuntimeApi>::Api:
runtime_api::Metadata<ComponentBlock<C>> + session::SessionKeys<ComponentBlock<C>>,
{
fn start_rpc(
client: Arc<ComponentClient<C>>,
system_send_back: mpsc::UnboundedSender<rpc::apis::system::Request<ComponentBlock<C>>>,
system_send_back: mpsc::UnboundedSender<rpc::system::Request<ComponentBlock<C>>>,
rpc_system_info: SystemInfo,
task_executor: TaskExecutor,
transaction_pool: Arc<TransactionPool<C::TransactionPoolApi>>,
rpc_extensions: impl rpc::RpcExtension<rpc::Metadata>,
keystore: KeyStorePtr,
) -> rpc::RpcHandler {
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(
) -> RpcHandler {
use rpc::{chain, state, author, system};
let subscriptions = rpc::Subscriptions::new(task_executor.clone());
let chain = chain::Chain::new(client.clone(), subscriptions.clone());
let state = state::State::new(client.clone(), subscriptions.clone());
let author = rpc::author::Author::new(
client,
transaction_pool,
subscriptions,
keystore,
);
let system = rpc::apis::system::System::new(rpc_system_info, system_send_back);
rpc::rpc_handler::<ComponentBlock<C>, ComponentExHash<C>, _, _, _, _>(
state,
chain,
author,
system,
)
let system = system::System::new(rpc_system_info, system_send_back);
rpc_servers::rpc_handler((
state::StateApi::to_delegate(state),
chain::ChainApi::to_delegate(chain),
author::AuthorApi::to_delegate(author),
system::SystemApi::to_delegate(system),
rpc_extensions,
))
}
}
@@ -299,7 +307,7 @@ pub trait ServiceTrait<C: Components>:
Deref<Target = Service<C>>
+ Send
+ 'static
+ StartRPC<C>
+ StartRpc<C>
+ MaintainTransactionPool<C>
+ OffchainWorker<C>
+ InitialSessionKeys<C>
@@ -308,7 +316,7 @@ impl<C: Components, T> ServiceTrait<C> for T where
T: Deref<Target = Service<C>>
+ Send
+ 'static
+ StartRPC<C>
+ StartRpc<C>
+ MaintainTransactionPool<C>
+ OffchainWorker<C>
+ InitialSessionKeys<C>
@@ -335,6 +343,8 @@ pub trait ServiceFactory: 'static + Sized {
type Genesis: RuntimeGenesis;
/// Other configuration for service members.
type Configuration: Default;
/// RPC initialisation.
type RpcExtensions: rpc::RpcExtension<rpc::Metadata>;
/// Extended full service type.
type FullService: ServiceTrait<FullComponents<Self>>;
/// Extended light service type.
@@ -407,6 +417,18 @@ pub trait ServiceFactory: 'static + Sized {
Err("Chain Specification doesn't contain any consensus_engine name".into())
}
}
/// Create custom RPC method handlers for full node.
fn build_full_rpc_extensions(
client: Arc<FullClient<Self>>,
transaction_pool: Arc<TransactionPool<Self::FullTransactionPoolApi>>,
) -> Self::RpcExtensions;
/// Create custom RPC method handlers for light node.
fn build_light_rpc_extensions(
client: Arc<LightClient<Self>>,
transaction_pool: Arc<TransactionPool<Self::LightTransactionPoolApi>>,
) -> Self::RpcExtensions;
}
/// A collection of types and function to generalize over full / light client type.
@@ -419,8 +441,10 @@ pub trait Components: Sized + 'static {
type Executor: 'static + client::CallExecutor<FactoryBlock<Self::Factory>, Blake2Hasher> + Send + Sync + Clone;
/// The type that implements the runtime API.
type RuntimeApi: Send + Sync;
/// A type that can start all runtime-dependent services.
/// The type that can start all runtime-dependent services.
type RuntimeServices: ServiceTrait<Self>;
/// The type that can extend the RPC methods.
type RpcExtensions: rpc::RpcExtension<rpc::Metadata>;
// TODO: Traitify transaction pool and allow people to implement their own. (#1242)
/// Extrinsic pool type.
type TransactionPoolApi: 'static + txpool::ChainApi<
@@ -468,6 +492,12 @@ pub trait Components: Sized + 'static {
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Option<Self::SelectChain>, error::Error>;
/// Build RPC extensions
fn build_rpc_extensions(
client: Arc<ComponentClient<Self>>,
transaction_pool: Arc<TransactionPool<Self::TransactionPoolApi>>,
) -> Self::RpcExtensions;
}
/// A struct that implement `Components` for the full client.
@@ -529,6 +559,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
type ImportQueue = Factory::FullImportQueue;
type RuntimeApi = Factory::RuntimeApi;
type RuntimeServices = Factory::FullService;
type RpcExtensions = Factory::RpcExtensions;
type SelectChain = Factory::SelectChain;
fn build_client(
@@ -594,6 +625,13 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
) -> Result<Option<Arc<dyn FinalityProofProvider<<Self::Factory as ServiceFactory>::Block>>>, error::Error> {
Factory::build_finality_proof_provider(client)
}
fn build_rpc_extensions(
client: Arc<ComponentClient<Self>>,
transaction_pool: Arc<TransactionPool<Self::TransactionPoolApi>>,
) -> Self::RpcExtensions {
Factory::build_full_rpc_extensions(client, transaction_pool)
}
}
/// A struct that implement `Components` for the light client.
@@ -655,6 +693,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
type ImportQueue = <Factory as ServiceFactory>::LightImportQueue;
type RuntimeApi = Factory::RuntimeApi;
type RuntimeServices = Factory::LightService;
type RpcExtensions = Factory::RpcExtensions;
type SelectChain = Factory::SelectChain;
fn build_client(
@@ -709,12 +748,20 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
) -> Result<Option<Arc<dyn FinalityProofProvider<<Self::Factory as ServiceFactory>::Block>>>, error::Error> {
Ok(None)
}
fn build_select_chain(
_config: &mut FactoryFullConfiguration<Self::Factory>,
_client: Arc<ComponentClient<Self>>
) -> Result<Option<Self::SelectChain>, error::Error> {
Ok(None)
}
fn build_rpc_extensions(
client: Arc<ComponentClient<Self>>,
transaction_pool: Arc<TransactionPool<Self::TransactionPoolApi>>,
) -> Self::RpcExtensions {
Factory::build_light_rpc_extensions(client, transaction_pool)
}
}
#[cfg(test)]