diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js
index 952002b60..7348487e7 100644
--- a/js/src/api/format/output.js
+++ b/js/src/api/format/output.js
@@ -140,6 +140,10 @@ export function outHwAccountInfo (infos) {
}, {});
}
+export function outNodeKind (info) {
+ return info;
+}
+
export function outNumber (number) {
return new BigNumber(number || 0);
}
diff --git a/js/src/api/format/output.spec.js b/js/src/api/format/output.spec.js
index c23751670..fabe30b32 100644
--- a/js/src/api/format/output.spec.js
+++ b/js/src/api/format/output.spec.js
@@ -16,7 +16,7 @@
import BigNumber from 'bignumber.js';
-import { outBlock, outAccountInfo, outAddress, outChainStatus, outDate, outHistogram, outHwAccountInfo, outNumber, outPeer, outPeers, outReceipt, outRecentDapps, outSyncing, outTransaction, outTrace, outVaultMeta } from './output';
+import { outBlock, outAccountInfo, outAddress, outChainStatus, outDate, outHistogram, outHwAccountInfo, outNodeKind, outNumber, outPeer, outPeers, outReceipt, outRecentDapps, outSyncing, outTransaction, outTrace, outVaultMeta } from './output';
import { isAddress, isBigNumber, isInstanceOf } from '../../../test/types';
describe('api/format/output', () => {
@@ -173,6 +173,14 @@ describe('api/format/output', () => {
});
});
+ describe('outNodeKind', () => {
+ it('formats the input as received', () => {
+ const kind = { availability: 'personal', capability: 'full' };
+
+ expect(outNodeKind(kind)).to.deep.equal(kind);
+ });
+ });
+
describe('outNumber', () => {
it('returns a BigNumber equalling the value', () => {
const bn = outNumber('0x123456');
diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js
index dba6e5d30..26cfac505 100644
--- a/js/src/api/rpc/parity/parity.js
+++ b/js/src/api/rpc/parity/parity.js
@@ -15,7 +15,7 @@
// along with Parity. If not, see .
import { inAddress, inAddresses, inData, inHex, inNumber16, inOptions, inBlockNumber } from '../../format/input';
-import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outHwAccountInfo, outNumber, outPeers, outRecentDapps, outTransaction, outVaultMeta } from '../../format/output';
+import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outHwAccountInfo, outNodeKind, outNumber, outPeers, outRecentDapps, outTransaction, outVaultMeta } from '../../format/output';
export default class Parity {
constructor (transport) {
@@ -290,6 +290,12 @@ export default class Parity {
.execute('parity_chain');
}
+ nodeKind () {
+ return this._transport
+ .execute('parity_nodeKind')
+ .then(outNodeKind);
+ }
+
chain () {
return this._transport
.execute('parity_chain');
diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js
index 1e6df05de..7a883726a 100644
--- a/js/src/jsonrpc/interfaces/parity.js
+++ b/js/src/jsonrpc/interfaces/parity.js
@@ -419,6 +419,30 @@ export default {
}
},
+ nodeKind: {
+ section: SECTION_NODE,
+ desc: 'Returns the node type availability and capability',
+ params: [],
+ returns: {
+ type: Object,
+ desc: 'Availability and Capability.',
+ details: {
+ availability: {
+ type: String,
+ desc: 'Availability, either `personal` or `public`.'
+ },
+ capability: {
+ type: String,
+ desc: 'Capability, either `full` or `light`.'
+ }
+ }
+ },
+ example: {
+ availability: 'personal',
+ capability: 'light'
+ }
+ },
+
netChain: {
section: SECTION_NET,
desc: 'Returns the name of the connected chain.',
diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs
index 545935417..46062b15a 100644
--- a/rpc/src/v1/impls/light/parity.rs
+++ b/rpc/src/v1/impls/light/parity.rs
@@ -333,4 +333,13 @@ impl Parity for ParityClient {
block_gap: gap.map(|(x, y)| (x.into(), y.into())),
})
}
+
+ fn node_kind(&self) -> Result<::v1::types::NodeKind, Error> {
+ use ::v1::types::{NodeKind, Availability, Capability};
+
+ Ok(NodeKind {
+ availability: Availability::Personal,
+ capability: Capability::Light,
+ })
+ }
}
diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs
index 2a7f85aa3..d6e16f267 100644
--- a/rpc/src/v1/impls/parity.rs
+++ b/rpc/src/v1/impls/parity.rs
@@ -372,4 +372,14 @@ impl Parity for ParityClient where
block_gap: gap.map(|(x, y)| (x.into(), y.into())),
})
}
+
+ fn node_kind(&self) -> Result<::v1::types::NodeKind, Error> {
+ use ::v1::types::{NodeKind, Availability, Capability};
+
+ // TODO [maciej]: public availability flag.
+ Ok(NodeKind {
+ availability: Availability::Personal,
+ capability: Capability::Full,
+ })
+ }
}
diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs
index 3af627037..e9b252af8 100644
--- a/rpc/src/v1/tests/mocked/parity.rs
+++ b/rpc/src/v1/tests/mocked/parity.rs
@@ -497,3 +497,14 @@ fn rpc_parity_chain_status() {
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
+
+#[test]
+fn rpc_parity_node_kind() {
+ let deps = Dependencies::new();
+ let io = deps.default_client();
+
+ let request = r#"{"jsonrpc": "2.0", "method": "parity_nodeKind", "params":[], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":{"availability":"personal","capability":"full"},"id":1}"#;
+
+ assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
+}
diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs
index 263adf6b2..8a15addae 100644
--- a/rpc/src/v1/traits/parity.rs
+++ b/rpc/src/v1/traits/parity.rs
@@ -194,5 +194,9 @@ build_rpc_trait! {
/// Get the current chain status.
#[rpc(name = "parity_chainStatus")]
fn chain_status(&self) -> Result;
+
+ /// Get node kind info.
+ #[rpc(name = "parity_nodeKind")]
+ fn node_kind(&self) -> Result<::v1::types::NodeKind, Error>;
}
}
diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs
index a4bfcb41f..0ec60a74f 100644
--- a/rpc/src/v1/types/mod.rs
+++ b/rpc/src/v1/types/mod.rs
@@ -30,6 +30,7 @@ mod hash;
mod histogram;
mod index;
mod log;
+mod node_kind;
mod provenance;
mod receipt;
mod rpc_settings;
@@ -58,6 +59,7 @@ pub use self::hash::{H64, H160, H256, H512, H520, H2048};
pub use self::histogram::Histogram;
pub use self::index::Index;
pub use self::log::Log;
+pub use self::node_kind::{NodeKind, Availability, Capability};
pub use self::provenance::{Origin, DappId};
pub use self::receipt::Receipt;
pub use self::rpc_settings::RpcSettings;
diff --git a/rpc/src/v1/types/node_kind.rs b/rpc/src/v1/types/node_kind.rs
new file mode 100644
index 000000000..5c96fafc6
--- /dev/null
+++ b/rpc/src/v1/types/node_kind.rs
@@ -0,0 +1,92 @@
+// Copyright 2015-2017 Parity Technologies (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 .
+
+//! Description of the node.
+
+/// Describes the kind of node. This information can provide a hint to
+/// applications about how to utilize the RPC.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct NodeKind {
+ /// The capability of the node.
+ pub capability: Capability,
+ /// Who the node is available to.
+ pub availability: Availability,
+}
+
+/// Who the node is available to.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub enum Availability {
+ /// A personal node, not intended to be available to everyone.
+ #[serde(rename="personal")]
+ Personal,
+ /// A public, open node.
+ #[serde(rename="public")]
+ Public,
+}
+
+/// The capability of the node.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub enum Capability {
+ /// A full node stores the full state and fully enacts incoming blocks.
+ #[serde(rename="full")]
+ Full,
+ /// A light node does a minimal header sync and fetches data as needed
+ /// from the network.
+ #[serde(rename="light")]
+ Light,
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{NodeKind, Availability, Capability};
+ use serde_json;
+
+ #[test]
+ fn availability() {
+ let personal = r#""personal""#;
+ let public = r#""public""#;
+
+ assert_eq!(serde_json::to_string(&Availability::Personal).unwrap(), personal);
+ assert_eq!(serde_json::to_string(&Availability::Public).unwrap(), public);
+
+ assert_eq!(serde_json::from_str::(personal).unwrap(), Availability::Personal);
+ assert_eq!(serde_json::from_str::(public).unwrap(), Availability::Public);
+ }
+
+ #[test]
+ fn capability() {
+ let light = r#""light""#;
+ let full = r#""full""#;
+
+ assert_eq!(serde_json::to_string(&Capability::Light).unwrap(), light);
+ assert_eq!(serde_json::to_string(&Capability::Full).unwrap(), full);
+
+ assert_eq!(serde_json::from_str::(light).unwrap(), Capability::Light);
+ assert_eq!(serde_json::from_str::(full).unwrap(), Capability::Full);
+ }
+
+ #[test]
+ fn node_kind() {
+ let kind = NodeKind {
+ capability: Capability::Full,
+ availability: Availability::Public,
+ };
+ let s = r#"{"capability":"full","availability":"public"}"#;
+
+ assert_eq!(serde_json::to_string(&kind).unwrap(), s);
+ assert_eq!(serde_json::from_str::(s).unwrap(), kind);
+ }
+}