diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index ece76f8b6d9..d49e75a78d4 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -53,6 +53,11 @@ export default class Parity { ); } + chainId () { + return this._transport + .execute('parity_chainId'); + } + chainStatus () { return this._transport .execute('parity_chainStatus') diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index b1e568d5f7d..997b7d43421 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -56,6 +56,16 @@ export default { } }, + chainId: { + desc: 'Returns the current chain ID used for tranaction signing.', + params: [], + returns: { + type: Quantity, + desc: 'The current blockchain chain ID', + example: '0x1' + } + }, + chainStatus: { section: SECTION_NET, desc: 'Returns the information on warp sync blocks', diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 821937edcc2..fd617ae8595 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -39,7 +39,7 @@ use v1::helpers::light_fetch::LightFetch; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ - Bytes, U256, H160, H256, H512, CallRequest, + Bytes, U256, U64, H160, H256, H512, CallRequest, Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, @@ -50,6 +50,7 @@ use Host; /// Parity implementation for light client. pub struct ParityClient { + client: Arc, light_dispatch: Arc, accounts: Arc, logger: Arc, @@ -84,6 +85,7 @@ impl ParityClient { dapps_address, ws_address, eip86_transition: client.eip86_transition(), + client: client, } } @@ -321,6 +323,10 @@ impl Parity for ParityClient { Err(errors::light_unimplemented(None)) } + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U64::from)) + } + fn chain(&self) -> Result { Ok(self.settings.chain.clone()) } diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index b12ed873b14..0f68e654f9b 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -44,7 +44,7 @@ use v1::helpers::accounts::unwrap_provider; use v1::metadata::Metadata; use v1::traits::Parity; use v1::types::{ - Bytes, U256, H160, H256, H512, CallRequest, + Bytes, U256, U64, H160, H256, H512, CallRequest, Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, @@ -201,6 +201,10 @@ impl Parity for ParityClient where Ok(self.settings.chain.clone()) } + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U64::from)) + } + fn chain(&self) -> Result { Ok(self.client.spec_name()) } diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index ee714c54ba0..9153a17b3b6 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -221,6 +221,17 @@ fn rpc_parity_extra_data() { assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_parity_chain_id() { + let deps = Dependencies::new(); + let io = deps.default_client(); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_chainId", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); +} + #[test] fn rpc_parity_default_extra_data() { use util::misc; diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 7a7f68cec0e..e902d605226 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -24,7 +24,7 @@ use futures::BoxFuture; use node_health::Health; use v1::types::{ - H160, H256, H512, U256, Bytes, CallRequest, + H160, H256, H512, U256, U64, Bytes, CallRequest, Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, @@ -172,6 +172,12 @@ build_rpc_trait! { #[rpc(name = "parity_mode")] fn mode(&self) -> Result; + /// Returns the chain ID used for transaction signing at the + /// current best block. An empty string is returned if not + /// available. + #[rpc(name = "parity_chainId")] + fn chain_id(&self) -> Result, Error>; + /// Get the chain name. Returns one of: "foundation", "kovan", &c. of a filename. #[rpc(name = "parity_chain")] fn chain(&self) -> Result; diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index 1407ebcf246..c6963f2cf6f 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -76,7 +76,7 @@ pub use self::trace_filter::TraceFilter; pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus}; pub use self::transaction_request::TransactionRequest; pub use self::transaction_condition::TransactionCondition; -pub use self::uint::{U128, U256}; +pub use self::uint::{U128, U256, U64}; pub use self::work::Work; // TODO [ToDr] Refactor to a proper type Vec of enums? diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index d5eb63b44a1..90d512c8652 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -20,7 +20,7 @@ use ethcore::miner; use ethcore::{contract_address, CreateContractAddress}; use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; use v1::helpers::errors; -use v1::types::{Bytes, H160, H256, U256, H512, TransactionCondition}; +use v1::types::{Bytes, H160, H256, U256, H512, U64, TransactionCondition}; /// Transaction #[derive(Debug, Default, Clone, PartialEq, Serialize)] @@ -60,7 +60,7 @@ pub struct Transaction { pub public_key: Option, /// The network id of the transaction, if any. #[serde(rename="chainId")] - pub chain_id: Option, + pub chain_id: Option, /// The standardised V field of the signature (0 or 1). #[serde(rename="standardV")] pub standard_v: U256, @@ -196,7 +196,7 @@ impl Transaction { }, raw: ::rlp::encode(&t.signed).into_vec().into(), public_key: t.recover_public().ok().map(Into::into), - chain_id: t.chain_id(), + chain_id: t.chain_id().map(U64::from), standard_v: t.standard_v().into(), v: t.original_v().into(), r: signature.r().into(), @@ -230,7 +230,7 @@ impl Transaction { }, raw: ::rlp::encode(&t).into_vec().into(), public_key: t.public_key().map(Into::into), - chain_id: t.chain_id(), + chain_id: t.chain_id().map(U64::from), standard_v: t.standard_v().into(), v: t.original_v().into(), r: signature.r().into(), diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs index 2de1ad46c1e..6c08370c5c5 100644 --- a/rpc/src/v1/types/uint.rs +++ b/rpc/src/v1/types/uint.rs @@ -59,12 +59,6 @@ macro_rules! impl_uint { } } - impl serde::Serialize for $name { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("0x{}", self.0.to_hex())) - } - } - impl<'a> serde::Deserialize<'a> for $name { fn deserialize(deserializer: D) -> Result<$name, D::Error> where D: serde::Deserializer<'a> { @@ -104,7 +98,25 @@ macro_rules! impl_uint { impl_uint!(U128, EthU128, 2); impl_uint!(U256, EthU256, 4); +impl_uint!(U64, u64, 1); + +impl serde::Serialize for U128 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&format!("0x{}", self.0.to_hex())) + } +} +impl serde::Serialize for U256 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&format!("0x{}", self.0.to_hex())) + } +} + +impl serde::Serialize for U64 { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + serializer.serialize_str(&format!("0x{:x}", self.0)) + } +} #[cfg(test)] mod tests {