From 6995f057bcf0be1ad4aa369b963fd0dc16793246 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 18 Aug 2017 17:17:24 +0800 Subject: [PATCH 01/11] Add RPC eth_chainId for querying the current blockchain chain ID Currently although we can use `net_version` RPC call to get the current network ID, there's no RPC for querying the chain ID. This makes it impossible to determine the current actual blockchain using the RPC. An ETH/ETC client can accidentally connect to an ETC/ETH RPC endpoint without knowing it unless it tries to sign a transaction or it fetch a transaction that is known to have signed with a chain ID. This has since caused trouble for application developers, such as MetaMask, to add multi-chain support. The same RPC endpoint is also about to be merged for ETC's go-ethereum: https://github.com/ethereumproject/go-ethereum/pull/336 --- rpc/src/v1/impls/eth.rs | 5 +++++ rpc/src/v1/impls/light/eth.rs | 4 ++++ rpc/src/v1/traits/eth.rs | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 17835485c04..476aa7cffc3 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -284,6 +284,11 @@ impl Eth for EthClient where Ok(format!("{}", version)) } + fn chain_id(&self) -> Result { + let client = take_weak!(self.client); + Ok(client.signing_network_id().map(|v| format!("0x{:x}", v)).unwrap_or("".to_string())) + } + fn syncing(&self) -> Result { use ethcore::snapshot::RestorationStatus; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index e45397f7db0..5409b7173fe 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -217,6 +217,10 @@ impl Eth for EthClient { Ok(format!("{}", ::light::net::MAX_PROTOCOL_VERSION)) } + fn chain_id(&self) -> Result { + Ok(self.client.signing_network_id().map(|v| format!("0x{:x}", v)).unwrap_or("".to_string())) + } + fn syncing(&self) -> Result { if self.sync.is_major_importing() { let chain_info = self.client.chain_info(); diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 94126333533..44d266db720 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -33,6 +33,12 @@ build_rpc_trait! { #[rpc(name = "eth_protocolVersion")] fn protocol_version(&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 = "eth_chainId")] + fn chain_id(&self) -> Result; + /// Returns an object with data about the sync status or false. (wtf?) #[rpc(name = "eth_syncing")] fn syncing(&self) -> Result; From 7f8f215de9c9ef5819d68b5acc18d6faac7e122a Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 18 Aug 2017 17:29:36 +0800 Subject: [PATCH 02/11] Add eth_chainId to js's web3 interface --- js/src/api/rpc/eth/eth.js | 5 +++++ js/src/views/RpcCalls/data/rpc.json | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/js/src/api/rpc/eth/eth.js b/js/src/api/rpc/eth/eth.js index ffde938ea95..1f060849ac1 100644 --- a/js/src/api/rpc/eth/eth.js +++ b/js/src/api/rpc/eth/eth.js @@ -22,6 +22,11 @@ export default class Eth { this._transport = transport; } + chainId () { + return this._transport + .execute('eth_chainId'); + } + accounts () { return this._transport .execute('eth_accounts') diff --git a/js/src/views/RpcCalls/data/rpc.json b/js/src/views/RpcCalls/data/rpc.json index ec85b7c5bf2..737cee45867 100644 --- a/js/src/views/RpcCalls/data/rpc.json +++ b/js/src/views/RpcCalls/data/rpc.json @@ -50,6 +50,14 @@ "inputFormatters": [], "outputFormatter": null }, + { + "name": "eth_chainId", + "desc": "Returns the current chain ID used for tranaction signing.", + "params": [], + "returns": "`String` - The current blockchain chain ID", + "inputFormatters": [], + "outputFormatter": null + }, { "name": "eth_syncing", "desc": "Returns an object with data about the sync status or `false`.", From fb354fc53c78dceed88ef7522cec98cb9f75ff9d Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 18 Aug 2017 17:35:07 +0800 Subject: [PATCH 03/11] Add a mocked test for eth_chainId --- rpc/src/v1/tests/mocked/eth.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 13840ba269d..dfceb8200cc 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -124,6 +124,14 @@ fn rpc_eth_protocol_version() { assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_eth_chain_id() { + let request = r#"{"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x1","id":1}"#; + + assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); +} + #[test] fn rpc_eth_syncing() { use ethcore::snapshot::RestorationStatus; From 87787d24b7e0cbe016d5d7d45003bc9e790a6ccb Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 18 Aug 2017 17:38:54 +0800 Subject: [PATCH 04/11] Add chainId in js's jsonrpc interfaces --- js/src/jsonrpc/interfaces/eth.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/js/src/jsonrpc/interfaces/eth.js b/js/src/jsonrpc/interfaces/eth.js index 6489a62ac24..a52b16e7638 100644 --- a/js/src/jsonrpc/interfaces/eth.js +++ b/js/src/jsonrpc/interfaces/eth.js @@ -60,6 +60,16 @@ The following options are possible for the \`defaultBlock\` parameter: } }, + chainId: { + desc: 'Returns the current chain ID used for tranaction signing.', + params: [], + returns: { + type: String, + desc: 'The current blockchain chain ID', + example: '0x1' + } + }, + call: { desc: 'Executes a new message call immediately without creating a transaction on the block chain.', params: [ From c3cfa1637a5cd3b9d4fe00ad4c9221e532cf86af Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 21 Aug 2017 20:23:32 +0800 Subject: [PATCH 05/11] Change return type for eth_chainId to `Option` --- js/src/jsonrpc/interfaces/eth.js | 2 +- js/src/views/RpcCalls/data/rpc.json | 2 +- rpc/src/v1/impls/eth.rs | 4 ++-- rpc/src/v1/impls/light/eth.rs | 4 ++-- rpc/src/v1/traits/eth.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/src/jsonrpc/interfaces/eth.js b/js/src/jsonrpc/interfaces/eth.js index a52b16e7638..0f41ce0b97b 100644 --- a/js/src/jsonrpc/interfaces/eth.js +++ b/js/src/jsonrpc/interfaces/eth.js @@ -64,7 +64,7 @@ The following options are possible for the \`defaultBlock\` parameter: desc: 'Returns the current chain ID used for tranaction signing.', params: [], returns: { - type: String, + type: Quantity, desc: 'The current blockchain chain ID', example: '0x1' } diff --git a/js/src/views/RpcCalls/data/rpc.json b/js/src/views/RpcCalls/data/rpc.json index 737cee45867..1d3ad657170 100644 --- a/js/src/views/RpcCalls/data/rpc.json +++ b/js/src/views/RpcCalls/data/rpc.json @@ -54,7 +54,7 @@ "name": "eth_chainId", "desc": "Returns the current chain ID used for tranaction signing.", "params": [], - "returns": "`String` - The current blockchain chain ID", + "returns": "`QUANTITY` - The current blockchain chain ID", "inputFormatters": [], "outputFormatter": null }, diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 476aa7cffc3..b4457b4f388 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -284,9 +284,9 @@ impl Eth for EthClient where Ok(format!("{}", version)) } - fn chain_id(&self) -> Result { + fn chain_id(&self) -> Result, Error> { let client = take_weak!(self.client); - Ok(client.signing_network_id().map(|v| format!("0x{:x}", v)).unwrap_or("".to_string())) + Ok(client.signing_network_id()) } fn syncing(&self) -> Result { diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 5409b7173fe..d1d001b56dd 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -217,8 +217,8 @@ impl Eth for EthClient { Ok(format!("{}", ::light::net::MAX_PROTOCOL_VERSION)) } - fn chain_id(&self) -> Result { - Ok(self.client.signing_network_id().map(|v| format!("0x{:x}", v)).unwrap_or("".to_string())) + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_network_id()) } fn syncing(&self) -> Result { diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 44d266db720..23a2cc3ab7d 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -37,7 +37,7 @@ build_rpc_trait! { /// current best block. An empty string is returned if not /// available. #[rpc(name = "eth_chainId")] - fn chain_id(&self) -> Result; + fn chain_id(&self) -> Result, Error>; /// Returns an object with data about the sync status or false. (wtf?) #[rpc(name = "eth_syncing")] From 9bea238b206b47067834d57b70ea45c257b19185 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 4 Sep 2017 17:44:12 +0800 Subject: [PATCH 06/11] Change name eth_chainId to parity_chainId --- js/src/api/rpc/eth/eth.js | 5 ----- js/src/api/rpc/parity/parity.js | 5 +++++ js/src/jsonrpc/interfaces/eth.js | 10 ---------- js/src/jsonrpc/interfaces/parity.js | 10 ++++++++++ js/src/views/RpcCalls/data/rpc.json | 8 -------- rpc/src/v1/impls/eth.rs | 5 ----- rpc/src/v1/impls/light/eth.rs | 4 ---- rpc/src/v1/impls/light/parity.rs | 6 ++++++ rpc/src/v1/impls/parity.rs | 5 +++++ rpc/src/v1/tests/mocked/eth.rs | 8 -------- rpc/src/v1/tests/mocked/parity.rs | 8 ++++++++ rpc/src/v1/traits/eth.rs | 6 ------ rpc/src/v1/traits/parity.rs | 6 ++++++ 13 files changed, 40 insertions(+), 46 deletions(-) diff --git a/js/src/api/rpc/eth/eth.js b/js/src/api/rpc/eth/eth.js index 1f060849ac1..ffde938ea95 100644 --- a/js/src/api/rpc/eth/eth.js +++ b/js/src/api/rpc/eth/eth.js @@ -22,11 +22,6 @@ export default class Eth { this._transport = transport; } - chainId () { - return this._transport - .execute('eth_chainId'); - } - accounts () { return this._transport .execute('eth_accounts') diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index 67409156302..28665af0cde 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -44,6 +44,11 @@ export default class Parity { .execute('parity_addReservedPeer', encode); } + chainId () { + return this._transport + .execute('parity_chainId'); + } + chainStatus () { return this._transport .execute('parity_chainStatus') diff --git a/js/src/jsonrpc/interfaces/eth.js b/js/src/jsonrpc/interfaces/eth.js index 0f41ce0b97b..6489a62ac24 100644 --- a/js/src/jsonrpc/interfaces/eth.js +++ b/js/src/jsonrpc/interfaces/eth.js @@ -60,16 +60,6 @@ The following options are possible for the \`defaultBlock\` parameter: } }, - chainId: { - desc: 'Returns the current chain ID used for tranaction signing.', - params: [], - returns: { - type: Quantity, - desc: 'The current blockchain chain ID', - example: '0x1' - } - }, - call: { desc: 'Executes a new message call immediately without creating a transaction on the block chain.', params: [ diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index 6ab5ea212b5..5126f41c8e7 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -55,6 +55,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/js/src/views/RpcCalls/data/rpc.json b/js/src/views/RpcCalls/data/rpc.json index 1d3ad657170..ec85b7c5bf2 100644 --- a/js/src/views/RpcCalls/data/rpc.json +++ b/js/src/views/RpcCalls/data/rpc.json @@ -50,14 +50,6 @@ "inputFormatters": [], "outputFormatter": null }, - { - "name": "eth_chainId", - "desc": "Returns the current chain ID used for tranaction signing.", - "params": [], - "returns": "`QUANTITY` - The current blockchain chain ID", - "inputFormatters": [], - "outputFormatter": null - }, { "name": "eth_syncing", "desc": "Returns an object with data about the sync status or `false`.", diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index b4457b4f388..17835485c04 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -284,11 +284,6 @@ impl Eth for EthClient where Ok(format!("{}", version)) } - fn chain_id(&self) -> Result, Error> { - let client = take_weak!(self.client); - Ok(client.signing_network_id()) - } - fn syncing(&self) -> Result { use ethcore::snapshot::RestorationStatus; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index d1d001b56dd..e45397f7db0 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -217,10 +217,6 @@ impl Eth for EthClient { Ok(format!("{}", ::light::net::MAX_PROTOCOL_VERSION)) } - fn chain_id(&self) -> Result, Error> { - Ok(self.client.signing_network_id()) - } - fn syncing(&self) -> Result { if self.sync.is_major_importing() { let chain_info = self.client.chain_info(); diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 63e1c64b6bd..8cb71d0b7e9 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -49,6 +49,7 @@ use v1::types::{ /// Parity implementation for light client. pub struct ParityClient { + client: Arc, light_dispatch: Arc, accounts: Arc, logger: Arc, @@ -80,6 +81,7 @@ impl ParityClient { dapps_interface: dapps_interface, dapps_port: dapps_port, eip86_transition: client.eip86_transition(), + client: client, } } @@ -320,6 +322,10 @@ impl Parity for ParityClient { Err(errors::light_unimplemented(None)) } + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_network_id()) + } + 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 689ba3e708a..0503ba63b95 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -199,6 +199,11 @@ impl Parity for ParityClient where Ok(self.settings.chain.clone()) } + fn chain_id(&self) -> Result, Error> { + let client = take_weak!(self.client); + Ok(client.signing_network_id()) + } + fn chain(&self) -> Result { Ok(take_weak!(self.client).spec_name()) } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index dfceb8200cc..13840ba269d 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -124,14 +124,6 @@ fn rpc_eth_protocol_version() { assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); } -#[test] -fn rpc_eth_chain_id() { - let request = r#"{"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":"0x1","id":1}"#; - - assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); -} - #[test] fn rpc_eth_syncing() { use ethcore::snapshot::RestorationStatus; diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 23b68e853bd..17d4106ea39 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -204,6 +204,14 @@ fn rpc_parity_extra_data() { assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_eth_chain_id() { + let request = r#"{"jsonrpc": "2.0", "method": "parity_chainId", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x1","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/eth.rs b/rpc/src/v1/traits/eth.rs index 23a2cc3ab7d..94126333533 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -33,12 +33,6 @@ build_rpc_trait! { #[rpc(name = "eth_protocolVersion")] fn protocol_version(&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 = "eth_chainId")] - fn chain_id(&self) -> Result, Error>; - /// Returns an object with data about the sync status or false. (wtf?) #[rpc(name = "eth_syncing")] fn syncing(&self) -> Result; diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 272d874955e..de1864ae22d 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -171,6 +171,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; From 29dcabb229838c978c2b3f3d719fddeedd59be56 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 4 Sep 2017 18:39:14 +0800 Subject: [PATCH 07/11] Wrong test name and missed var for rpc_parity_chain_id test --- rpc/src/v1/tests/mocked/parity.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 17d4106ea39..888de219a1b 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -205,7 +205,10 @@ fn rpc_parity_extra_data() { } #[test] -fn rpc_eth_chain_id() { +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":"0x1","id":1}"#; From cf8e1894b6b0b531dcb379cdcd2752429b6e4c71 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Sep 2017 05:12:28 +0800 Subject: [PATCH 08/11] Use U256 to return chainId and fix for master u64 returns decimal integer, and there seems to be no type called U64. So here I use U256 to return the hex integer. --- rpc/src/v1/impls/light/parity.rs | 4 ++-- rpc/src/v1/impls/parity.rs | 5 ++--- rpc/src/v1/traits/parity.rs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 263ac1d4f02..db836a01b5f 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -322,8 +322,8 @@ impl Parity for ParityClient { Err(errors::light_unimplemented(None)) } - fn chain_id(&self) -> Result, Error> { - Ok(self.client.signing_network_id()) + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U256::from)) } fn chain(&self) -> Result { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index aa8f9b4e44f..07d400fbb37 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -200,9 +200,8 @@ impl Parity for ParityClient where Ok(self.settings.chain.clone()) } - fn chain_id(&self) -> Result, Error> { - let client = take_weak!(self.client); - Ok(client.signing_network_id()) + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U256::from)) } fn chain(&self) -> Result { diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index f8aa6eb7d0e..9de6835c77a 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -176,7 +176,7 @@ build_rpc_trait! { /// current best block. An empty string is returned if not /// available. #[rpc(name = "parity_chainId")] - fn chain_id(&self) -> Result, Error>; + fn chain_id(&self) -> Result, Error>; /// Get the chain name. Returns one of: "foundation", "kovan", &c. of a filename. #[rpc(name = "parity_chain")] From b8beb213f40be75ad4b447911063aea76a895dff Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Sep 2017 05:48:17 +0800 Subject: [PATCH 09/11] Fix chainID test Before EIP155 fork number, chainID should be null. --- rpc/src/v1/tests/mocked/parity.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index f9bb3a9f4e9..dbd411955c6 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -226,7 +226,7 @@ fn rpc_parity_chain_id() { let io = deps.default_client(); let request = r#"{"jsonrpc": "2.0", "method": "parity_chainId", "params": [], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":"0x1","id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } From 4da73e9234ebcbecf1859bf9da53012dba48c94e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Sep 2017 20:33:33 +0800 Subject: [PATCH 10/11] Change both parity_chainId and transaction::chainId to use U64 This makes it consistent that all chain ids returned are hex string. --- rpc/src/v1/impls/light/parity.rs | 6 +++--- rpc/src/v1/impls/parity.rs | 6 +++--- rpc/src/v1/traits/parity.rs | 4 ++-- rpc/src/v1/types/mod.rs | 2 +- rpc/src/v1/types/transaction.rs | 8 ++++---- rpc/src/v1/types/uint.rs | 24 ++++++++++++++++++------ 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index db836a01b5f..bf0b8ecce57 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, @@ -322,8 +322,8 @@ impl Parity for ParityClient { Err(errors::light_unimplemented(None)) } - fn chain_id(&self) -> Result, Error> { - Ok(self.client.signing_chain_id().map(U256::from)) + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U64::from)) } fn chain(&self) -> Result { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 07d400fbb37..90511cf15c5 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, @@ -200,8 +200,8 @@ impl Parity for ParityClient where Ok(self.settings.chain.clone()) } - fn chain_id(&self) -> Result, Error> { - Ok(self.client.signing_chain_id().map(U256::from)) + fn chain_id(&self) -> Result, Error> { + Ok(self.client.signing_chain_id().map(U64::from)) } fn chain(&self) -> Result { diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index 9de6835c77a..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, @@ -176,7 +176,7 @@ build_rpc_trait! { /// current best block. An empty string is returned if not /// available. #[rpc(name = "parity_chainId")] - fn chain_id(&self) -> Result, Error>; + fn chain_id(&self) -> Result, Error>; /// Get the chain name. Returns one of: "foundation", "kovan", &c. of a filename. #[rpc(name = "parity_chain")] 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..6501381e485 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{}", self.0)) + } +} #[cfg(test)] mod tests { From 1831fff0eac57ba6373a1a886cd5f9fac4d44dff Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Sep 2017 21:22:59 +0800 Subject: [PATCH 11/11] Fix wrong U64 serialization --- rpc/src/v1/types/uint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/src/v1/types/uint.rs b/rpc/src/v1/types/uint.rs index 6501381e485..6c08370c5c5 100644 --- a/rpc/src/v1/types/uint.rs +++ b/rpc/src/v1/types/uint.rs @@ -114,7 +114,7 @@ impl serde::Serialize for U256 { impl serde::Serialize for U64 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(&format!("0x{}", self.0)) + serializer.serialize_str(&format!("0x{:x}", self.0)) } }