From e942f86bd759d7918ebcea7f8c2c9f4a36a2a839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 29 Apr 2016 20:52:08 +0200 Subject: [PATCH] Modules RPC (#1019) --- parity/rpc.rs | 24 ++++++++++++++++++---- rpc/src/v1/impls/mod.rs | 2 ++ rpc/src/v1/impls/rpc.rs | 44 ++++++++++++++++++++++++++++++++++++++++ rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/rpc.rs | 38 ++++++++++++++++++++++++++++++++++ rpc/src/v1/traits/mod.rs | 2 ++ rpc/src/v1/traits/rpc.rs | 38 ++++++++++++++++++++++++++++++++++ 7 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 rpc/src/v1/impls/rpc.rs create mode 100644 rpc/src/v1/tests/rpc.rs create mode 100644 rpc/src/v1/traits/rpc.rs diff --git a/parity/rpc.rs b/parity/rpc.rs index 7fb496782..6a71cf45a 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . +use std::collections::BTreeMap; use std::str::FromStr; use std::sync::Arc; use std::net::SocketAddr; @@ -90,21 +91,36 @@ pub fn setup_rpc_server( use ethcore_rpc::v1::*; let server = Server::new(); + let mut modules = BTreeMap::new(); for api in apis.into_iter() { match api { - "web3" => server.add_delegate(Web3Client::new().to_delegate()), - "net" => server.add_delegate(NetClient::new(&deps.sync).to_delegate()), + "web3" => { + modules.insert("web3".to_owned(), "1.0".to_owned()); + server.add_delegate(Web3Client::new().to_delegate()); + }, + "net" => { + modules.insert("web3".to_owned(), "1.0".to_owned()); + server.add_delegate(NetClient::new(&deps.sync).to_delegate()); + }, "eth" => { + modules.insert("eth".to_owned(), "1.0".to_owned()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); }, - "personal" => server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()), - "ethcore" => server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()), + "personal" => { + modules.insert("personal".to_owned(), "1.0".to_owned()); + server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()) + }, + "ethcore" => { + // not adding to modules, since `ethcore` is not supported in geth + server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()) + }, _ => { die!("{}: Invalid API name to be enabled.", api); }, } } + server.add_delegate(RpcClient::new(modules).to_delegate()); let start_result = server.start_http(url, cors_domain); match start_result { Err(RpcServerError::IoError(err)) => die_with_io_error("RPC", err), diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index e504f3126..8747811d0 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -30,10 +30,12 @@ mod eth; mod net; mod personal; mod ethcore; +mod rpc; pub use self::web3::Web3Client; pub use self::eth::{EthClient, EthFilterClient}; pub use self::net::NetClient; pub use self::personal::PersonalClient; pub use self::ethcore::EthcoreClient; +pub use self::rpc::RpcClient; diff --git a/rpc/src/v1/impls/rpc.rs b/rpc/src/v1/impls/rpc.rs new file mode 100644 index 000000000..215834f17 --- /dev/null +++ b/rpc/src/v1/impls/rpc.rs @@ -0,0 +1,44 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! RPC generic methods implementation. +use std::collections::BTreeMap; +use jsonrpc_core::*; +use v1::traits::Rpc; + +/// RPC generic methods implementation. +pub struct RpcClient { + modules: BTreeMap, +} + +impl RpcClient { + /// Creates new `RpcClient`. + pub fn new(modules: BTreeMap) -> Self { + RpcClient { + modules: modules + } + } +} + +impl Rpc for RpcClient { + fn modules(&self, _: Params) -> Result { + let modules = self.modules.iter().fold(BTreeMap::new(), |mut map, (k, v)| { + map.insert(k.to_owned(), Value::String(v.to_owned())); + map + }); + Ok(Value::Object(modules)) + } +} diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index b5ab73084..367a26554 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -25,5 +25,5 @@ mod helpers; pub mod tests; -pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore}; +pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore, Rpc}; pub use self::impls::*; diff --git a/rpc/src/v1/tests/rpc.rs b/rpc/src/v1/tests/rpc.rs new file mode 100644 index 000000000..b2c58dda6 --- /dev/null +++ b/rpc/src/v1/tests/rpc.rs @@ -0,0 +1,38 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +use std::collections::BTreeMap; +use jsonrpc_core::IoHandler; +use v1::{Rpc, RpcClient}; + + +fn rpc_client() -> RpcClient { + let mut modules = BTreeMap::new(); + modules.insert("rpc".to_owned(), "1.0".to_owned()); + RpcClient::new(modules) +} + +#[test] +fn rpc_modules() { + let rpc = rpc_client().to_delegate(); + let io = IoHandler::new(); + io.add_delegate(rpc); + + let request = r#"{"jsonrpc": "2.0", "method": "modules", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"eth": "1.0"},"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index a15c8b8c9..bcddc04b5 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -25,9 +25,11 @@ pub mod eth; pub mod net; pub mod personal; pub mod ethcore; +pub mod rpc; pub use self::web3::Web3; pub use self::eth::{Eth, EthFilter}; pub use self::net::Net; pub use self::personal::Personal; pub use self::ethcore::Ethcore; +pub use self::rpc::Rpc; diff --git a/rpc/src/v1/traits/rpc.rs b/rpc/src/v1/traits/rpc.rs new file mode 100644 index 000000000..9d19efcd7 --- /dev/null +++ b/rpc/src/v1/traits/rpc.rs @@ -0,0 +1,38 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! RPC interface. + +use std::sync::Arc; +use jsonrpc_core::*; + +/// RPC Interface. +pub trait Rpc: Sized + Send + Sync + 'static { + + /// Returns supported modules. + fn modules(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Should be used to convert object to io delegate. + fn to_delegate(self) -> IoDelegate { + let mut delegate = IoDelegate::new(Arc::new(self)); + // Geth 1.3.6 compatibility + delegate.add_method("modules", Rpc::modules); + // Geth 1.4.0 compatibility + delegate.add_method("rpc_modules", Rpc::modules); + delegate + } +} +