diff --git a/bin/oe/cli/mod.rs b/bin/oe/cli/mod.rs
index 54e229957..f07422940 100644
--- a/bin/oe/cli/mod.rs
+++ b/bin/oe/cli/mod.rs
@@ -409,9 +409,9 @@ usage! {
"--jsonrpc-interface=[IP]",
"Specify the hostname portion of the HTTP JSON-RPC API server, IP should be an interface's IP address, or all (all interfaces) or local.",
- ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
+ ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
"--jsonrpc-apis=[APIS]",
- "Specify the APIs available through the HTTP JSON-RPC interface using a comma-delimited list of API names. Possible names are: all, safe, debug, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces",
+ "Specify the APIs available through the HTTP JSON-RPC interface using a comma-delimited list of API names. Possible names are: all, safe, debug, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc",
ARG arg_jsonrpc_hosts: (String) = "none", or |c: &Config| c.rpc.as_ref()?.hosts.as_ref().map(|vec| vec.join(",")),
"--jsonrpc-hosts=[HOSTS]",
@@ -450,9 +450,9 @@ usage! {
"--ws-interface=[IP]",
"Specify the hostname portion of the WebSockets JSON-RPC server, IP should be an interface's IP address, or all (all interfaces) or local.",
- ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
+ ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
"--ws-apis=[APIS]",
- "Specify the JSON-RPC APIs available through the WebSockets interface using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces",
+ "Specify the JSON-RPC APIs available through the WebSockets interface using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc",
ARG arg_ws_origins: (String) = "parity://*,chrome-extension://*,moz-extension://*", or |c: &Config| c.websockets.as_ref()?.origins.as_ref().map(|vec| vec.join(",")),
"--ws-origins=[URL]",
@@ -492,9 +492,9 @@ usage! {
"--ipc-path=[PATH]",
"Specify custom path for JSON-RPC over IPC service.",
- ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
+ ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")),
"--ipc-apis=[APIS]",
- "Specify custom API set available via JSON-RPC over IPC using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces",
+ "Specify custom API set available via JSON-RPC over IPC using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc",
["Secret Store Options"]
FLAG flag_no_secretstore: (bool) = false, or |c: &Config| c.secretstore.as_ref()?.disable.clone(),
@@ -1312,7 +1312,7 @@ mod tests {
arg_jsonrpc_port: 8545u16,
arg_jsonrpc_interface: "local".into(),
arg_jsonrpc_cors: "null".into(),
- arg_jsonrpc_apis: "web3,eth,net,parity,traces,secretstore".into(),
+ arg_jsonrpc_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
arg_jsonrpc_hosts: "none".into(),
arg_jsonrpc_server_threads: None,
arg_jsonrpc_threads: 4,
@@ -1324,7 +1324,7 @@ mod tests {
flag_no_ws: false,
arg_ws_port: 8546u16,
arg_ws_interface: "local".into(),
- arg_ws_apis: "web3,eth,net,parity,traces,secretstore".into(),
+ arg_ws_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
arg_ws_origins: "none".into(),
arg_ws_hosts: "none".into(),
arg_ws_max_connections: 100,
@@ -1333,7 +1333,7 @@ mod tests {
// IPC
flag_no_ipc: false,
arg_ipc_path: "$HOME/.parity/jsonrpc.ipc".into(),
- arg_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,secretstore"
+ arg_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc,secretstore"
.into(),
// METRICS
diff --git a/bin/oe/cli/tests/config.full.toml b/bin/oe/cli/tests/config.full.toml
index 37b01cafc..0d0f7aec1 100644
--- a/bin/oe/cli/tests/config.full.toml
+++ b/bin/oe/cli/tests/config.full.toml
@@ -39,7 +39,7 @@ disable = false
port = 8545
interface = "local"
cors = ["null"]
-apis = ["web3", "eth", "net", "parity", "traces", "secretstore"]
+apis = ["web3", "eth", "net", "parity", "traces", "rpc", "secretstore"]
hosts = ["none"]
allow_missing_blocks = false
@@ -48,13 +48,13 @@ disable = false
port = 8546
interface = "local"
origins = ["none"]
-apis = ["web3", "eth", "net", "parity", "traces", "secretstore"]
+apis = ["web3", "eth", "net", "parity", "traces", "rpc", "secretstore"]
hosts = ["none"]
[ipc]
disable = false
path = "$HOME/.parity/jsonrpc.ipc"
-apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "secretstore"]
+apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "rpc", "secretstore"]
[secretstore]
disable = false
diff --git a/bin/oe/configuration.rs b/bin/oe/configuration.rs
index fe7a71917..b0b1b9215 100644
--- a/bin/oe/configuration.rs
+++ b/bin/oe/configuration.rs
@@ -1741,7 +1741,7 @@ mod tests {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),
_ => panic!("Incorrect rpc apis"),
}
- // "web3,eth,net,personal,parity,parity_set,traces,parity_accounts");
+ // "web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts");
assert_eq!(c.http_conf.hosts, None);
}
_ => panic!("Should be Cmd::Run"),
@@ -1762,7 +1762,7 @@ mod tests {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),
_ => panic!("Incorrect rpc apis"),
}
- // "web3,eth,net,personal,parity,parity_set,traces,parity_accounts");
+ // "web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts");
assert_eq!(c.http_conf.hosts, None);
}
_ => panic!("Should be Cmd::Run"),
diff --git a/bin/oe/rpc_apis.rs b/bin/oe/rpc_apis.rs
index 0de19f768..0acb88646 100644
--- a/bin/oe/rpc_apis.rs
+++ b/bin/oe/rpc_apis.rs
@@ -14,7 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with OpenEthereum. If not, see .
-use std::{cmp::PartialEq, collections::HashSet, str::FromStr, sync::Arc};
+use std::{
+ cmp::PartialEq,
+ collections::{BTreeMap, HashSet},
+ str::FromStr,
+ sync::Arc,
+};
pub use parity_rpc::signer::SignerService;
@@ -51,6 +56,8 @@ pub enum Api {
Parity,
/// Traces (Safe)
Traces,
+ /// Rpc (Safe)
+ Rpc,
/// Parity PubSub - Generic Publish-Subscriber (Safety depends on other APIs exposed).
ParityPubSub,
/// Parity Accounts extensions (UNSAFE: Passwords, Side Effects (new account))
@@ -80,6 +87,7 @@ impl FromStr for Api {
"parity_set" => Ok(ParitySet),
"personal" => Ok(Personal),
"pubsub" => Ok(EthPubSub),
+ "rpc" => Ok(Rpc),
"secretstore" => Ok(SecretStore),
"signer" => Ok(Signer),
"traces" => Ok(Traces),
@@ -146,6 +154,30 @@ impl FromStr for ApiSet {
}
}
+fn to_modules(apis: &HashSet) -> BTreeMap {
+ let mut modules = BTreeMap::new();
+ for api in apis {
+ let (name, version) = match *api {
+ Api::Debug => ("debug", "1.0"),
+ Api::Eth => ("eth", "1.0"),
+ Api::EthPubSub => ("pubsub", "1.0"),
+ Api::Net => ("net", "1.0"),
+ Api::Parity => ("parity", "1.0"),
+ Api::ParityAccounts => ("parity_accounts", "1.0"),
+ Api::ParityPubSub => ("parity_pubsub", "1.0"),
+ Api::ParitySet => ("parity_set", "1.0"),
+ Api::Personal => ("personal", "1.0"),
+ Api::Rpc => ("rpc", "1.0"),
+ Api::SecretStore => ("secretstore", "1.0"),
+ Api::Signer => ("signer", "1.0"),
+ Api::Traces => ("traces", "1.0"),
+ Api::Web3 => ("web3", "1.0"),
+ };
+ modules.insert(name.into(), version.into());
+ }
+ modules
+}
+
macro_rules! add_signing_methods {
($namespace:ident, $handler:expr, $deps:expr, $dispatch:expr) => {{
let deps = &$deps;
@@ -376,6 +408,10 @@ impl FullDependencies {
);
}
Api::Traces => handler.extend_with(TracesClient::new(&self.client).to_delegate()),
+ Api::Rpc => {
+ let modules = to_modules(&apis);
+ handler.extend_with(RpcClient::new(modules).to_delegate());
+ }
Api::SecretStore => {
#[cfg(feature = "accounts")]
handler.extend_with(SecretStoreClient::new(&self.accounts).to_delegate());
@@ -409,11 +445,17 @@ impl ApiSet {
}
pub fn list_apis(&self) -> HashSet {
- let mut public_list: HashSet =
- [Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity]
- .iter()
- .cloned()
- .collect();
+ let mut public_list: HashSet = [
+ Api::Web3,
+ Api::Net,
+ Api::Eth,
+ Api::EthPubSub,
+ Api::Parity,
+ Api::Rpc,
+ ]
+ .iter()
+ .cloned()
+ .collect();
match *self {
ApiSet::List(ref apis) => apis.clone(),
@@ -470,6 +512,7 @@ mod test {
assert_eq!(Api::ParityAccounts, "parity_accounts".parse().unwrap());
assert_eq!(Api::ParitySet, "parity_set".parse().unwrap());
assert_eq!(Api::Traces, "traces".parse().unwrap());
+ assert_eq!(Api::Rpc, "rpc".parse().unwrap());
assert_eq!(Api::SecretStore, "secretstore".parse().unwrap());
assert!("rp".parse::().is_err());
}
@@ -498,6 +541,7 @@ mod test {
Api::Parity,
Api::ParityPubSub,
Api::Traces,
+ Api::Rpc,
]
.into_iter()
.collect();
@@ -515,6 +559,7 @@ mod test {
Api::Parity,
Api::ParityPubSub,
Api::Traces,
+ Api::Rpc,
// semi-safe
Api::ParityAccounts,
]
@@ -536,6 +581,7 @@ mod test {
Api::Parity,
Api::ParityPubSub,
Api::Traces,
+ Api::Rpc,
Api::SecretStore,
Api::ParityAccounts,
Api::ParitySet,
@@ -562,6 +608,7 @@ mod test {
Api::Parity,
Api::ParityPubSub,
Api::Traces,
+ Api::Rpc,
Api::SecretStore,
Api::ParityAccounts,
Api::ParitySet,
@@ -587,6 +634,7 @@ mod test {
Api::Parity,
Api::ParityPubSub,
Api::Traces,
+ Api::Rpc,
]
.into_iter()
.collect()
diff --git a/crates/rpc/src/v1/impls/mod.rs b/crates/rpc/src/v1/impls/mod.rs
index c8a1c64bc..5d7aa04d4 100644
--- a/crates/rpc/src/v1/impls/mod.rs
+++ b/crates/rpc/src/v1/impls/mod.rs
@@ -28,6 +28,7 @@ mod parity_set;
#[cfg(any(test, feature = "accounts"))]
mod personal;
mod pubsub;
+mod rpc;
#[cfg(any(test, feature = "accounts"))]
mod secretstore;
mod signer;
@@ -53,6 +54,7 @@ pub use self::{
parity::ParityClient,
parity_set::ParitySetClient,
pubsub::PubSubClient,
+ rpc::RpcClient,
signer::SignerClient,
signing::SigningQueueClient,
signing_unsafe::SigningUnsafeClient,
diff --git a/crates/rpc/src/v1/impls/rpc.rs b/crates/rpc/src/v1/impls/rpc.rs
new file mode 100644
index 000000000..521818620
--- /dev/null
+++ b/crates/rpc/src/v1/impls/rpc.rs
@@ -0,0 +1,66 @@
+// Copyright 2015-2020 Parity Technologies (UK) Ltd.
+// This file is part of OpenEthereum.
+
+// OpenEthereum 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.
+
+// OpenEthereum 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 OpenEthereum. If not, see .
+
+//! RPC generic methods implementation.
+use jsonrpc_core::Result;
+use std::collections::BTreeMap;
+use v1::traits::Rpc;
+
+/// RPC generic methods implementation.
+pub struct RpcClient {
+ modules: BTreeMap,
+ valid_apis: Vec,
+}
+
+impl RpcClient {
+ /// Creates new `RpcClient`.
+ pub fn new(modules: BTreeMap) -> Self {
+ // geth 1.3.6 fails upon receiving unknown api
+ let valid_apis = vec!["web3", "eth", "net", "personal", "rpc"];
+
+ RpcClient {
+ modules,
+ valid_apis: valid_apis.into_iter().map(ToOwned::to_owned).collect(),
+ }
+ }
+}
+
+impl Rpc for RpcClient {
+ fn rpc_modules(&self) -> Result> {
+ let modules = self
+ .modules
+ .iter()
+ .fold(BTreeMap::new(), |mut map, (k, v)| {
+ map.insert(k.to_owned(), v.to_owned());
+ map
+ });
+
+ Ok(modules)
+ }
+
+ fn modules(&self) -> Result> {
+ let modules = self
+ .modules
+ .iter()
+ .filter(|&(k, _v)| self.valid_apis.contains(k))
+ .fold(BTreeMap::new(), |mut map, (k, v)| {
+ map.insert(k.to_owned(), v.to_owned());
+ map
+ });
+
+ Ok(modules)
+ }
+}
diff --git a/crates/rpc/src/v1/mod.rs b/crates/rpc/src/v1/mod.rs
index 1645cecd8..fe4357c15 100644
--- a/crates/rpc/src/v1/mod.rs
+++ b/crates/rpc/src/v1/mod.rs
@@ -48,7 +48,7 @@ pub use self::{
metadata::Metadata,
traits::{
Debug, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccounts,
- ParityAccountsInfo, ParitySet, ParitySetAccounts, ParitySigning, Personal, PubSub,
+ ParityAccountsInfo, ParitySet, ParitySetAccounts, ParitySigning, Personal, PubSub, Rpc,
SecretStore, Signer, Traces, Web3,
},
types::Origin,
diff --git a/crates/rpc/src/v1/tests/mocked/mod.rs b/crates/rpc/src/v1/tests/mocked/mod.rs
index 878e0b050..82d08e2ca 100644
--- a/crates/rpc/src/v1/tests/mocked/mod.rs
+++ b/crates/rpc/src/v1/tests/mocked/mod.rs
@@ -29,6 +29,7 @@ mod parity_set;
#[cfg(any(test, feature = "accounts"))]
mod personal;
mod pubsub;
+mod rpc;
#[cfg(any(test, feature = "accounts"))]
mod secretstore;
mod signer;
diff --git a/crates/rpc/src/v1/tests/mocked/rpc.rs b/crates/rpc/src/v1/tests/mocked/rpc.rs
new file mode 100644
index 000000000..6dc677c61
--- /dev/null
+++ b/crates/rpc/src/v1/tests/mocked/rpc.rs
@@ -0,0 +1,52 @@
+// Copyright 2015-2020 Parity Technologies (UK) Ltd.
+// This file is part of OpenEthereum.
+
+// OpenEthereum 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.
+
+// OpenEthereum 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 OpenEthereum. If not, see .
+
+use jsonrpc_core::IoHandler;
+use std::collections::BTreeMap;
+use v1::{Rpc, RpcClient};
+
+fn rpc_client() -> RpcClient {
+ let mut modules = BTreeMap::new();
+ modules.insert("rpc".to_owned(), "1.0".to_owned());
+ modules.insert("web3".to_owned(), "1.0".to_owned());
+ modules.insert("ethcore".to_owned(), "1.0".to_owned());
+ RpcClient::new(modules)
+}
+
+#[test]
+fn modules() {
+ let rpc = rpc_client().to_delegate();
+ let mut io = IoHandler::new();
+ io.extend_with(rpc);
+
+ let request = r#"{"jsonrpc": "2.0", "method": "modules", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":{"rpc":"1.0","web3":"1.0"},"id":1}"#;
+
+ assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_modules() {
+ let rpc = rpc_client().to_delegate();
+ let mut io = IoHandler::new();
+ io.extend_with(rpc);
+
+ let request = r#"{"jsonrpc": "2.0", "method": "rpc_modules", "params": [], "id": 1}"#;
+ let response =
+ r#"{"jsonrpc":"2.0","result":{"ethcore":"1.0","rpc":"1.0","web3":"1.0"},"id":1}"#;
+
+ assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
+}
diff --git a/crates/rpc/src/v1/traits/mod.rs b/crates/rpc/src/v1/traits/mod.rs
index 046d54cb1..37c732b37 100644
--- a/crates/rpc/src/v1/traits/mod.rs
+++ b/crates/rpc/src/v1/traits/mod.rs
@@ -27,6 +27,7 @@ pub mod parity_set;
pub mod parity_signing;
pub mod personal;
pub mod pubsub;
+pub mod rpc;
pub mod secretstore;
pub mod signer;
pub mod traces;
@@ -44,6 +45,7 @@ pub use self::{
parity_signing::ParitySigning,
personal::Personal,
pubsub::PubSub,
+ rpc::Rpc,
secretstore::SecretStore,
signer::Signer,
traces::Traces,
diff --git a/crates/rpc/src/v1/traits/rpc.rs b/crates/rpc/src/v1/traits/rpc.rs
new file mode 100644
index 000000000..1348279f0
--- /dev/null
+++ b/crates/rpc/src/v1/traits/rpc.rs
@@ -0,0 +1,36 @@
+// Copyright 2015-2020 Parity Technologies (UK) Ltd.
+// This file is part of OpenEthereum.
+
+// OpenEthereum 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.
+
+// OpenEthereum 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 OpenEthereum. If not, see .
+
+//! RPC interface.
+
+use std::collections::BTreeMap;
+
+use jsonrpc_core::Result;
+use jsonrpc_derive::rpc;
+
+/// RPC Interface.
+#[rpc(server)]
+pub trait Rpc {
+ /// Returns supported modules for Geth 1.3.6
+ /// @ignore
+ #[rpc(name = "modules")]
+ fn modules(&self) -> Result>;
+
+ /// Returns supported modules for Geth 1.4.0
+ /// @ignore
+ #[rpc(name = "rpc_modules")]
+ fn rpc_modules(&self) -> Result>;
+}