node kind RPC (#5025)

* node kind RPC

* JS interface for parity_nodeKind
This commit is contained in:
Robert Habermeier 2017-03-27 17:30:19 +02:00 committed by Gav Wood
parent a12583f762
commit 62158601fb
10 changed files with 172 additions and 2 deletions

View File

@ -140,6 +140,10 @@ export function outHwAccountInfo (infos) {
}, {}); }, {});
} }
export function outNodeKind (info) {
return info;
}
export function outNumber (number) { export function outNumber (number) {
return new BigNumber(number || 0); return new BigNumber(number || 0);
} }

View File

@ -16,7 +16,7 @@
import BigNumber from 'bignumber.js'; 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'; import { isAddress, isBigNumber, isInstanceOf } from '../../../test/types';
describe('api/format/output', () => { 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', () => { describe('outNumber', () => {
it('returns a BigNumber equalling the value', () => { it('returns a BigNumber equalling the value', () => {
const bn = outNumber('0x123456'); const bn = outNumber('0x123456');

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inAddress, inAddresses, inData, inHex, inNumber16, inOptions, inBlockNumber } from '../../format/input'; 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 { export default class Parity {
constructor (transport) { constructor (transport) {
@ -290,6 +290,12 @@ export default class Parity {
.execute('parity_chain'); .execute('parity_chain');
} }
nodeKind () {
return this._transport
.execute('parity_nodeKind')
.then(outNodeKind);
}
chain () { chain () {
return this._transport return this._transport
.execute('parity_chain'); .execute('parity_chain');

View File

@ -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: { netChain: {
section: SECTION_NET, section: SECTION_NET,
desc: 'Returns the name of the connected chain.', desc: 'Returns the name of the connected chain.',

View File

@ -333,4 +333,13 @@ impl Parity for ParityClient {
block_gap: gap.map(|(x, y)| (x.into(), y.into())), 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,
})
}
} }

View File

@ -372,4 +372,14 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
block_gap: gap.map(|(x, y)| (x.into(), y.into())), 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,
})
}
} }

View File

@ -497,3 +497,14 @@ fn rpc_parity_chain_status() {
assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); 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()));
}

View File

@ -194,5 +194,9 @@ build_rpc_trait! {
/// Get the current chain status. /// Get the current chain status.
#[rpc(name = "parity_chainStatus")] #[rpc(name = "parity_chainStatus")]
fn chain_status(&self) -> Result<ChainStatus, Error>; fn chain_status(&self) -> Result<ChainStatus, Error>;
/// Get node kind info.
#[rpc(name = "parity_nodeKind")]
fn node_kind(&self) -> Result<::v1::types::NodeKind, Error>;
} }
} }

View File

@ -30,6 +30,7 @@ mod hash;
mod histogram; mod histogram;
mod index; mod index;
mod log; mod log;
mod node_kind;
mod provenance; mod provenance;
mod receipt; mod receipt;
mod rpc_settings; 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::histogram::Histogram;
pub use self::index::Index; pub use self::index::Index;
pub use self::log::Log; pub use self::log::Log;
pub use self::node_kind::{NodeKind, Availability, Capability};
pub use self::provenance::{Origin, DappId}; pub use self::provenance::{Origin, DappId};
pub use self::receipt::Receipt; pub use self::receipt::Receipt;
pub use self::rpc_settings::RpcSettings; pub use self::rpc_settings::RpcSettings;

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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::<Availability>(personal).unwrap(), Availability::Personal);
assert_eq!(serde_json::from_str::<Availability>(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::<Capability>(light).unwrap(), Capability::Light);
assert_eq!(serde_json::from_str::<Capability>(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::<NodeKind>(s).unwrap(), kind);
}
}