diff --git a/Cargo.lock b/Cargo.lock index b796a298c0359..9fafbf6f49cec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1194,7 +1194,7 @@ name = "polkadot" version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "polkadot-cli 0.1.0", + "polkadot-cli 0.2.0", ] [[package]] @@ -1217,7 +1217,7 @@ dependencies = [ [[package]] name = "polkadot-cli" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/demo/cli/src/lib.rs b/demo/cli/src/lib.rs index 306f26e8885c5..6a2730280db63 100644 --- a/demo/cli/src/lib.rs +++ b/demo/cli/src/lib.rs @@ -61,6 +61,19 @@ impl substrate_rpc::author::AuthorApi for DummyPool { } } +struct DummySystem; +impl substrate_rpc::system::SystemApi for DummySystem { + fn system_name(&self) -> substrate_rpc::system::error::Result { + Ok("substrate-demo".into()) + } + fn system_version(&self) -> substrate_rpc::system::error::Result { + Ok(crate_version!().into()) + } + fn system_chain(&self) -> substrate_rpc::system::error::Result { + Ok("default".into()) + } +} + /// Parse command line arguments and start the node. /// /// IANA unassigned port ranges that we could use: @@ -142,7 +155,7 @@ pub fn run(args: I) -> error::Result<()> where let _rpc_servers = { let handler = || { let chain = rpc::apis::chain::Chain::new(client.clone(), core.remote()); - rpc::rpc_handler(client.clone(), chain, DummyPool) + rpc::rpc_handler(client.clone(), chain, DummyPool, DummySystem) }; let http_address = "127.0.0.1:9933".parse().unwrap(); let ws_address = "127.0.0.1:9944".parse().unwrap(); diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index 5ec179b273493..f80b3b1d9fc18 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-cli" -version = "0.1.0" +version = "0.2.0" authors = ["Parity Technologies "] description = "Polkadot node implementation in Rust." diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index 0934755f20d5d..d26ebf75568fc 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -95,6 +95,26 @@ impl substrate_rpc::author::AuthorApi for RpcTransactionPool { } } +struct Configuration(service::Configuration); + +impl substrate_rpc::system::SystemApi for Configuration { + fn system_name(&self) -> substrate_rpc::system::error::Result { + Ok("parity-polkadot".into()) + } + + fn system_version(&self) -> substrate_rpc::system::error::Result { + Ok(crate_version!().into()) + } + + fn system_chain(&self) -> substrate_rpc::system::error::Result { + Ok(match self.0.chain_spec { + ChainSpec::Development => "dev", + ChainSpec::LocalTestnet => "local", + ChainSpec::PoC1Testnet => "poc-1", + }.into()) + } +} + /// Parse command line arguments and start the node. /// /// IANA unassigned port ranges that we could use: @@ -189,12 +209,12 @@ pub fn run(args: I) -> error::Result<()> where config.keys = matches.values_of("key").unwrap_or_default().map(str::to_owned).collect(); match role == service::Role::LIGHT { - true => run_until_exit(core, service::new_light(config)?, &matches), - false => run_until_exit(core, service::new_full(config)?, &matches), + true => run_until_exit(core, service::new_light(config.clone())?, &matches, config), + false => run_until_exit(core, service::new_full(config.clone())?, &matches, config), } } -fn run_until_exit(mut core: reactor::Core, service: service::Service, matches: &clap::ArgMatches) -> error::Result<()> +fn run_until_exit(mut core: reactor::Core, service: service::Service, matches: &clap::ArgMatches, config: service::Configuration) -> error::Result<()> where B: client::backend::Backend + Send + Sync + 'static, E: client::CallExecutor + Send + Sync + 'static, @@ -222,7 +242,7 @@ fn run_until_exit(mut core: reactor::Core, service: service::Service inner: service.transaction_pool(), network: service.network(), }; - rpc::rpc_handler(service.client(), chain, pool) + rpc::rpc_handler(service.client(), chain, pool, Configuration(config.clone())) }; ( start_server(http_address, |address| rpc::start_http(address, handler())), diff --git a/polkadot/service/src/config.rs b/polkadot/service/src/config.rs index 177675ea704a0..16b39631b9d9a 100644 --- a/polkadot/service/src/config.rs +++ b/polkadot/service/src/config.rs @@ -22,6 +22,7 @@ pub use network::NetworkConfiguration; /// The chain specification (this should eventually be replaced by a more general JSON-based chain /// specification). +#[derive(Clone)] pub enum ChainSpec { /// Whatever the current runtime is, with just Alice as an auth. Development, @@ -62,3 +63,21 @@ impl Default for Configuration { } } } + +impl Clone for Configuration { + fn clone(&self) -> Configuration { + Configuration { + roles: self.roles.clone(), + transaction_pool: transaction_pool::Options { + max_count: self.transaction_pool.max_count.clone(), + max_mem_usage: self.transaction_pool.max_mem_usage.clone(), + max_per_sender: self.transaction_pool.max_per_sender.clone(), + }, + network: self.network.clone(), + keystore_path: self.keystore_path.clone(), + database_path: self.database_path.clone(), + keys: self.keys.clone(), + chain_spec: self.chain_spec.clone(), + } + } +} diff --git a/substrate/rpc-servers/src/lib.rs b/substrate/rpc-servers/src/lib.rs index 0d0157553ec44..05e4cd70fd9ba 100644 --- a/substrate/rpc-servers/src/lib.rs +++ b/substrate/rpc-servers/src/lib.rs @@ -34,19 +34,22 @@ type Metadata = apis::metadata::Metadata; type RpcHandler = pubsub::PubSubHandler; /// Construct rpc `IoHandler` -pub fn rpc_handler( +pub fn rpc_handler( state: S, chain: C, author: A, + system: Y, ) -> RpcHandler where S: apis::state::StateApi, C: apis::chain::ChainApi, A: apis::author::AuthorApi, + Y: apis::system::SystemApi, { let mut io = pubsub::PubSubHandler::default(); io.extend_with(state.to_delegate()); io.extend_with(chain.to_delegate()); io.extend_with(author.to_delegate()); + io.extend_with(system.to_delegate()); io } diff --git a/substrate/rpc/src/lib.rs b/substrate/rpc/src/lib.rs index 54f8739e33f2e..59f278b3a787c 100644 --- a/substrate/rpc/src/lib.rs +++ b/substrate/rpc/src/lib.rs @@ -45,3 +45,4 @@ pub mod author; pub mod chain; pub mod metadata; pub mod state; +pub mod system; diff --git a/substrate/rpc/src/system/error.rs b/substrate/rpc/src/system/error.rs new file mode 100644 index 0000000000000..2fe155f23e3fe --- /dev/null +++ b/substrate/rpc/src/system/error.rs @@ -0,0 +1,42 @@ +// Copyright 2017 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 . + +//! System RPC module errors. + +use rpc; + +error_chain! { + errors { + /// Not implemented yet + Unimplemented { + description("not yet implemented"), + display("Method Not Implemented"), + } + } +} + +impl From for rpc::Error { + fn from(e: Error) -> Self { + match e { + Error(ErrorKind::Unimplemented, _) => rpc::Error { + code: rpc::ErrorCode::ServerError(-1), + message: "Not implemented yet".into(), + data: None, + }, + _ => rpc::Error::internal_error(), + } + } +} diff --git a/substrate/rpc/src/system/mod.rs b/substrate/rpc/src/system/mod.rs new file mode 100644 index 0000000000000..56d06be9e5cda --- /dev/null +++ b/substrate/rpc/src/system/mod.rs @@ -0,0 +1,41 @@ +// Copyright 2017 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 . + +//! Substrate system API. + +pub mod error; + +#[cfg(test)] +mod tests; + +use self::error::Result; + +build_rpc_trait! { + /// Substrate system RPC API + pub trait SystemApi { + /// Get the node's implementation name. Plain old string. + #[rpc(name = "system_name")] + fn system_name(&self) -> Result; + + /// Get the node implementation's version. Should be a semver string. + #[rpc(name = "system_version")] + fn system_version(&self) -> Result; + + /// Get the chain's type. Given as a string identifier. + #[rpc(name = "system_chain")] + fn system_chain(&self) -> Result; + } +} diff --git a/substrate/rpc/src/system/tests.rs b/substrate/rpc/src/system/tests.rs new file mode 100644 index 0000000000000..f22cd5a157779 --- /dev/null +++ b/substrate/rpc/src/system/tests.rs @@ -0,0 +1,54 @@ +// Copyright 2017 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 . + +use super::*; +use super::error::*; + +impl SystemApi for () { + fn system_name(&self) -> Result { + Ok("testclient".into()) + } + fn system_version(&self) -> Result { + Ok("0.2.0".into()) + } + fn system_chain(&self) -> Result { + Ok("testchain".into()) + } +} + +#[test] +fn system_name_works() { + assert_eq!( + SystemApi::system_name(&()).unwrap(), + "testclient".to_owned() + ); +} + +#[test] +fn system_version_works() { + assert_eq!( + SystemApi::system_version(&()).unwrap(), + "0.2.0".to_owned() + ); +} + +#[test] +fn system_chain_works() { + assert_eq!( + SystemApi::system_chain(&()).unwrap(), + "testchain".to_owned() + ); +}