From 84a48142defadd8b48654299c5d4d532f992261d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 10 Mar 2016 19:50:04 +0100 Subject: [PATCH 01/12] Add more geth options. --- parity/main.rs | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 68d45bc04..cced0ed0f 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -70,9 +70,9 @@ Parity. Ethereum Client. Copyright 2015, 2016 Ethcore (UK) Limited Usage: - parity daemon [options] [ --no-bootstrap | ... ] + parity daemon [options] parity account (new | list) - parity [options] [ --no-bootstrap | ... ] + parity [options] Protocol Options: --chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file @@ -85,13 +85,13 @@ Protocol Options: --identity NAME Specify your node's name. Networking Options: - --no-bootstrap Don't bother trying to connect to any nodes initially. - --listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304]. - --public-address URL Specify the IP/port on which peers may connect. - --address URL Equivalent to --listen-address URL --public-address URL. - --peers NUM Try to maintain that many peers [default: 25]. + --no-bootstrap Don't bother trying to connect to standard bootnodes. + --bootnodes NODES Specify additional comma-separated bootnodes. --no-discovery Disable new peer discovery. - --no-upnp Disable trying to figure out the correct public adderss over UPnP. + --peers NUM Try to maintain that many peers [default: 25]. + --port PORT Override the port for the node to listen on, supercedes --address. + --nat METHOD Specify method to use for determining public address. Must be one of: any, none, + upnp, extip:(IP) [default: upnp]. --node-key KEY Specify node secret key, either as 64-character hex string or input to SHA3 operation. API and Console Options: @@ -101,16 +101,11 @@ API and Console Options: --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null]. --jsonrpc-apis APIS Specify the APIs available through the JSONRPC interface. APIS is a comma-delimited list of API name. Possible name are web3, eth and net. [default: web3,eth,net]. - --rpc Equivalent to --jsonrpc (geth-compatible). - --rpcaddr HOST Equivalent to --jsonrpc-addr HOST (geth-compatible). - --rpcport PORT Equivalent to --jsonrpc-port PORT (geth-compatible). - --rpcapi APIS Equivalent to --jsonrpc-apis APIS (geth-compatible). - --rpccorsdomain URL Equivalent to --jsonrpc-cors URL (geth-compatible). Sealing/Mining Options: --author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63]. - --extradata STRING Specify a custom extra-data for authored blocks, no more than 32 characters. + --extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters. Memory Footprint Options: --cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384]. @@ -119,6 +114,18 @@ Memory Footprint Options: --cache MEGABYTES Set total amount of cache to use for the entire system, mutually exclusive with other cache options (geth-compatible). +Geth-Compatibility Options + --rpc Equivalent to --jsonrpc. + --rpcaddr HOST Equivalent to --jsonrpc-addr HOST. + --rpcport PORT Equivalent to --jsonrpc-port PORT. + --rpcapi APIS Equivalent to --jsonrpc-apis APIS. + --rpccorsdomain URL Equivalent to --jsonrpc-cors URL. + --maxpeers COUNT Equivalent to --peers COUNT. + --nodekey KEY Equivalent to --node-key KEY. + --nodiscover Equivalent to --no-discovery. + --etherbase ADDRESS Equivalent to --author ADDRESS. + --extradata STRING Equivalent to --extra-data STRING. + Miscellaneous Options: -l --logging LOGGING Specify the logging level. -v --version Show information about version. @@ -145,7 +152,7 @@ struct Args { flag_listen_address: String, flag_public_address: Option, flag_address: Option, - flag_peers: usize, + flag_maxpeers: usize, flag_no_discovery: bool, flag_no_upnp: bool, flag_node_key: Option, @@ -323,7 +330,7 @@ impl Configuration { ret.public_address = public; ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).unwrap_or_else(|_| s.sha3())); ret.discovery_enabled = !self.args.flag_no_discovery; - ret.ideal_peers = self.args.flag_peers as u32; + ret.ideal_peers = self.args.flag_maxpeers as u32; let mut net_path = PathBuf::from(&self.path()); net_path.push("network"); ret.config_path = Some(net_path.to_str().unwrap().to_owned()); From 29916edb91092d95a5a08c10075bea2bb7098a3f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 10 Mar 2016 21:36:45 +0100 Subject: [PATCH 02/12] More geth compatibility. --- parity/main.rs | 101 +++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index cced0ed0f..402017f3c 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -37,7 +37,7 @@ extern crate rpassword; #[cfg(feature = "rpc")] extern crate ethcore_rpc as rpc; -use std::net::{SocketAddr}; +use std::net::{SocketAddr, IpAddr}; use std::env; use std::process::exit; use std::path::PathBuf; @@ -77,21 +77,19 @@ Usage: Protocol Options: --chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, homestead, mainnet, morden, or testnet [default: homestead]. - --testnet Equivalent to --chain testnet (geth-compatible). - --networkid INDEX Override the network identifier from the chain we are on. - --archive Client should not prune the state/storage trie. - -d --datadir PATH Specify the database & configuration directory path [default: $HOME/.parity] + --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity] --keys-path PATH Specify the path for JSON key files to be found [default: $HOME/.web3/keys] --identity NAME Specify your node's name. + --archive Client should not prune the state/storage trie. Networking Options: - --no-bootstrap Don't bother trying to connect to standard bootnodes. - --bootnodes NODES Specify additional comma-separated bootnodes. - --no-discovery Disable new peer discovery. + --port PORT Override the port on which the node should listen [default: 30303]. --peers NUM Try to maintain that many peers [default: 25]. - --port PORT Override the port for the node to listen on, supercedes --address. --nat METHOD Specify method to use for determining public address. Must be one of: any, none, - upnp, extip:(IP) [default: upnp]. + upnp, extip:(IP) [default: any]. + --bootnodes NODES Specify additional comma-separated bootnodes. + --no-bootstrap Don't bother trying to connect to standard bootnodes. + --no-discovery Disable new peer discovery. --node-key KEY Specify node secret key, either as 64-character hex string or input to SHA3 operation. API and Console Options: @@ -115,6 +113,9 @@ Memory Footprint Options: other cache options (geth-compatible). Geth-Compatibility Options + --datadir PATH Equivalent to --db-path PATH. + --testnet Equivalent to --chain testnet. + --networkid INDEX Override the network identifier from the chain we are on. --rpc Equivalent to --jsonrpc. --rpcaddr HOST Equivalent to --jsonrpc-addr HOST. --rpcport PORT Equivalent to --jsonrpc-port PORT. @@ -139,22 +140,18 @@ struct Args { cmd_new: bool, cmd_list: bool, arg_pid_file: String, - arg_enode: Vec, flag_chain: String, - flag_testnet: bool, - flag_datadir: String, - flag_networkid: Option, + flag_db_path: String, flag_identity: String, flag_cache: Option, flag_keys_path: String, flag_archive: bool, + flag_bootnodes: Option, flag_no_bootstrap: bool, - flag_listen_address: String, - flag_public_address: Option, - flag_address: Option, - flag_maxpeers: usize, + flag_port: u16, + flag_peers: usize, flag_no_discovery: bool, - flag_no_upnp: bool, + flag_nat: String, flag_node_key: Option, flag_cache_pref_size: usize, flag_cache_max_size: usize, @@ -164,15 +161,24 @@ struct Args { flag_jsonrpc_port: u16, flag_jsonrpc_cors: String, flag_jsonrpc_apis: String, + flag_logging: Option, + flag_version: bool, + // geth-compatibility... + flag_nodekey: Option, + flag_nodiscover: bool, + flag_maxpeers: Option, + flag_author: String, + flag_extra_data: Option, + flag_datadir: Option, + flag_extradata: Option, + flag_etherbase: Option, flag_rpc: bool, flag_rpcaddr: Option, flag_rpcport: Option, flag_rpccorsdomain: Option, flag_rpcapi: Option, - flag_logging: Option, - flag_version: bool, - flag_author: String, - flag_extra_data: Option, + flag_testnet: bool, + flag_networkid: Option, } fn setup_log(init: &Option) { @@ -252,15 +258,17 @@ impl Configuration { } fn path(&self) -> String { - self.args.flag_datadir.replace("$HOME", env::home_dir().unwrap().to_str().unwrap()) + let d = self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path); + d.replace("$HOME", env::home_dir().unwrap().to_str().unwrap()) } fn author(&self) -> Address { - Address::from_str(&self.args.flag_author).unwrap_or_else(|_| die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", self.args.flag_author)) + let d = self.args.flag_etherbase.as_ref().unwrap_or(&self.args.flag_author); + Address::from_str(d).unwrap_or_else(|_| die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", self.args.flag_author)) } fn extra_data(&self) -> Bytes { - match self.args.flag_extra_data { + match self.args.flag_extradata.as_ref().or(self.args.flag_extra_data.as_ref()) { Some(ref x) if x.len() <= 32 => x.as_bytes().to_owned(), None => version_data(), Some(ref x) => { die!("{}: Extra data must be at most 32 characters.", x); } @@ -292,45 +300,40 @@ impl Configuration { } fn init_nodes(&self, spec: &Spec) -> Vec { - if self.args.flag_no_bootstrap { Vec::new() } else { - match self.args.arg_enode.len() { - 0 => spec.nodes().clone(), - _ => self.args.arg_enode.iter().map(|s| Self::normalize_enode(s).unwrap_or_else(||die!("{}: Invalid node address format given for a boot node.", s))).collect(), - } + let mut r = if self.args.flag_no_bootstrap { Vec::new() } else { spec.nodes().clone() }; + if let Some(ref x) = self.args.flag_bootnodes { + r.extend(x.split(",").map(|s| Self::normalize_enode(s).unwrap_or_else(||die!("{}: Invalid node address format given for a boot node.", s)))); } + r } #[cfg_attr(all(nightly, feature="dev"), allow(useless_format))] fn net_addresses(&self) -> (Option, Option) { - let mut listen_address = None; - let mut public_address = None; + let listen_address = Some(SocketAddr::new(IpAddr::from_str("127.0.0.1").unwrap(), self.args.flag_port)); + + let host = if self.args.flag_nat.starts_with("extip:") { + &self.args.flag_nat[6..] + } else { + "127.0.0.1" + }; + let public_address = Some(SocketAddr::new( + IpAddr::from_str(&host).unwrap_or_else(|_| die!("{}: Invalid host given with --net extip:", host)), + self.args.flag_port + )); - if let Some(ref a) = self.args.flag_address { - public_address = Some(SocketAddr::from_str(a.as_ref()).unwrap_or_else(|_| die!("{}: Invalid listen/public address given with --address", a))); - listen_address = public_address; - } - if listen_address.is_none() { - listen_address = Some(SocketAddr::from_str(self.args.flag_listen_address.as_ref()).unwrap_or_else(|_| die!("{}: Invalid listen/public address given with --listen-address", self.args.flag_listen_address))); - } - if let Some(ref a) = self.args.flag_public_address { - if public_address.is_some() { - die!("Conflicting flags provided: --address and --public-address"); - } - public_address = Some(SocketAddr::from_str(a.as_ref()).unwrap_or_else(|_| die!("{}: Invalid listen/public address given with --public-address", a))); - } (listen_address, public_address) } fn net_settings(&self, spec: &Spec) -> NetworkConfiguration { let mut ret = NetworkConfiguration::new(); - ret.nat_enabled = !self.args.flag_no_upnp; + ret.nat_enabled = self.args.flag_nat == "any" || self.args.flag_nat == "upnp"; ret.boot_nodes = self.init_nodes(spec); let (listen, public) = self.net_addresses(); ret.listen_address = listen; ret.public_address = public; ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).unwrap_or_else(|_| s.sha3())); - ret.discovery_enabled = !self.args.flag_no_discovery; - ret.ideal_peers = self.args.flag_maxpeers as u32; + ret.discovery_enabled = !self.args.flag_no_discovery && !self.args.flag_nodiscover; + ret.ideal_peers = self.args.flag_maxpeers.unwrap_or(self.args.flag_peers) as u32; let mut net_path = PathBuf::from(&self.path()); net_path.push("network"); ret.config_path = Some(net_path.to_str().unwrap().to_owned()); From d9c462a3d3bd5a15b5c8dc6c8424b85b4179349c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 11 Mar 2016 10:05:27 +0100 Subject: [PATCH 03/12] Use proper listen address. Tidyups. --- parity/main.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index d6c3516d0..732e94f02 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -302,25 +302,21 @@ impl Configuration { fn init_nodes(&self, spec: &Spec) -> Vec { let mut r = if self.args.flag_no_bootstrap { Vec::new() } else { spec.nodes().clone() }; if let Some(ref x) = self.args.flag_bootnodes { - r.extend(x.split(",").map(|s| Self::normalize_enode(s).unwrap_or_else(||die!("{}: Invalid node address format given for a boot node.", s)))); + r.extend(x.split(",").map(|s| Self::normalize_enode(s).unwrap_or_else(|| die!("{}: Invalid node address format given for a boot node.", s)))); } r } #[cfg_attr(all(nightly, feature="dev"), allow(useless_format))] fn net_addresses(&self) -> (Option, Option) { - let listen_address = Some(SocketAddr::new(IpAddr::from_str("127.0.0.1").unwrap(), self.args.flag_port)); - - let host = if self.args.flag_nat.starts_with("extip:") { - &self.args.flag_nat[6..] + let listen_address = Some(SocketAddr::new(IpAddr::from_str("0.0.0.0").unwrap(), self.args.flag_port)); + let public_address = if self.args.flag_nat.starts_with("extip:") { + let host = &self.args.flag_nat[6..]; + let host = IpAddr::from_str(host).unwrap_or_else(|_| die!("Invalid host given with `--nat extip:{}`", host)); + Some(SocketAddr::new(host, self.args.flag_port)) } else { - "127.0.0.1" + listen_address.clone() }; - let public_address = Some(SocketAddr::new( - IpAddr::from_str(&host).unwrap_or_else(|_| die!("{}: Invalid host given with --net extip:", host)), - self.args.flag_port - )); - (listen_address, public_address) } From 34a120e1270288ffafc3518f8a4fb681ee5cfdf2 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 10:17:20 +0100 Subject: [PATCH 04/12] net tests --- rpc/src/v1/impls/net.rs | 4 +- rpc/src/v1/mod.rs | 3 +- rpc/src/v1/tests/helpers/mod.rs | 19 ++++++++ rpc/src/v1/tests/helpers/sync_provider.rs | 57 +++++++++++++++++++++++ rpc/src/v1/tests/mod.rs | 21 ++++++++- rpc/src/v1/tests/net.rs | 52 +++++++++++++++++++++ sync/src/chain.rs | 1 + 7 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 rpc/src/v1/tests/helpers/mod.rs create mode 100644 rpc/src/v1/tests/helpers/sync_provider.rs create mode 100644 rpc/src/v1/tests/net.rs diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index 5e67bf252..1918073e3 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -36,10 +36,10 @@ impl NetClient where S: SyncProvider { impl Net for NetClient where S: SyncProvider + 'static { fn version(&self, _: Params) -> Result { - Ok(Value::U64(take_weak!(self.sync).status().protocol_version as u64)) + Ok(Value::String(format!("{}", take_weak!(self.sync).status().protocol_version).to_owned())) } fn peer_count(&self, _params: Params) -> Result { - Ok(Value::U64(take_weak!(self.sync).status().num_peers as u64)) + Ok(Value::String(format!("0x{:x}", take_weak!(self.sync).status().num_peers as u64).to_owned())) } } diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 104a8b3f0..b82a20e89 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -21,9 +21,10 @@ pub mod traits; mod impls; mod types; +mod helpers; + #[cfg(test)] mod tests; -mod helpers; pub use self::traits::{Web3, Eth, EthFilter, Personal, Net}; pub use self::impls::*; diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs new file mode 100644 index 000000000..501bfb2d3 --- /dev/null +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2015, 2016 Ethcore (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 . + +mod sync_provider; + +pub use self::sync_provider::{Config, TestSyncProvider}; diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs new file mode 100644 index 000000000..b6d9241dd --- /dev/null +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -0,0 +1,57 @@ +// Copyright 2015, 2016 Ethcore (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 . + +use ethcore::transaction::SignedTransaction; +use ethsync::{SyncProvider, SyncStatus, SyncState}; + +pub struct Config { + pub protocol_version: u8, + pub num_peers: usize, +} + +pub struct TestSyncProvider { + status: SyncStatus, +} + +impl TestSyncProvider { + pub fn new(config: Config) -> Self { + TestSyncProvider { + status: SyncStatus { + state: SyncState::NotSynced, + protocol_version: config.protocol_version, + start_block_number: 0, + last_imported_block_number: None, + highest_block_number: None, + blocks_total: 0, + blocks_received: 0, + num_peers: config.num_peers, + num_active_peers: 0, + mem_used: 0, + }, + } + } +} + +impl SyncProvider for TestSyncProvider { + fn status(&self) -> SyncStatus { + self.status.clone() + } + + fn insert_transaction(&self, _transaction: SignedTransaction) { + unimplemented!() + } +} + diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs index bdf4567b6..5ef74987c 100644 --- a/rpc/src/v1/tests/mod.rs +++ b/rpc/src/v1/tests/mod.rs @@ -1 +1,20 @@ -//TODO: load custom blockchain state and test +// Copyright 2015, 2016 Ethcore (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 . + +//!TODO: load custom blockchain state and test + +mod net; +mod helpers; diff --git a/rpc/src/v1/tests/net.rs b/rpc/src/v1/tests/net.rs new file mode 100644 index 000000000..f6c4ae2e9 --- /dev/null +++ b/rpc/src/v1/tests/net.rs @@ -0,0 +1,52 @@ +// Copyright 2015, 2016 Ethcore (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 . + +use std::sync::Arc; +use jsonrpc_core::IoHandler; +use v1::{Net, NetClient}; +use v1::tests::helpers::{Config, TestSyncProvider}; + +#[test] +fn rpc_net_version() { + let sync = Arc::new(TestSyncProvider::new(Config { + protocol_version: 65, + num_peers: 120, + })); + let net = NetClient::new(&sync).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(net); + + let request = r#"{"jsonrpc": "2.0", "method": "net_version", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"65","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_string())); +} + +#[test] +fn rpc_net_peer_count() { + let sync = Arc::new(TestSyncProvider::new(Config { + protocol_version: 65, + num_peers: 120, + })); + let net = NetClient::new(&sync).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(net); + + let request = r#"{"jsonrpc": "2.0", "method": "net_peerCount", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x78","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_string())); +} diff --git a/sync/src/chain.rs b/sync/src/chain.rs index da3908a1e..da25c72de 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -120,6 +120,7 @@ pub enum SyncState { } /// Syncing status and statistics +#[derive(Clone)] pub struct SyncStatus { /// State pub state: SyncState, From 8e52510dbb45642105f3fb4dab5e6fc166225fff Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 10:21:25 +0100 Subject: [PATCH 05/12] implemented net_listening method --- rpc/src/v1/impls/net.rs | 5 +++++ rpc/src/v1/tests/net.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index 1918073e3..e52fc0bd4 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -42,4 +42,9 @@ impl Net for NetClient where S: SyncProvider + 'static { fn peer_count(&self, _params: Params) -> Result { Ok(Value::String(format!("0x{:x}", take_weak!(self.sync).status().num_peers as u64).to_owned())) } + + fn is_listening(&self, _: Params) -> Result { + // right now (11 march 2016), we are always listening for incoming connections + Ok(Value::Bool(true)) + } } diff --git a/rpc/src/v1/tests/net.rs b/rpc/src/v1/tests/net.rs index f6c4ae2e9..9cb0bd189 100644 --- a/rpc/src/v1/tests/net.rs +++ b/rpc/src/v1/tests/net.rs @@ -50,3 +50,19 @@ fn rpc_net_peer_count() { assert_eq!(io.handle_request(request), Some(response.to_string())); } + +#[test] +fn rpc_net_listening() { + let sync = Arc::new(TestSyncProvider::new(Config { + protocol_version: 65, + num_peers: 120, + })); + let net = NetClient::new(&sync).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(net); + + let request = r#"{"jsonrpc": "2.0", "method": "net_listening", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_string())); +} From 18939462c392a3c175b69dc6002454c7baeb55ca Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 11:03:43 +0100 Subject: [PATCH 06/12] sync_provider function --- rpc/src/v1/tests/net.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/rpc/src/v1/tests/net.rs b/rpc/src/v1/tests/net.rs index 9cb0bd189..792e469d8 100644 --- a/rpc/src/v1/tests/net.rs +++ b/rpc/src/v1/tests/net.rs @@ -19,12 +19,16 @@ use jsonrpc_core::IoHandler; use v1::{Net, NetClient}; use v1::tests::helpers::{Config, TestSyncProvider}; -#[test] -fn rpc_net_version() { - let sync = Arc::new(TestSyncProvider::new(Config { +fn sync_provider() -> Arc { + Arc::new(TestSyncProvider::new(Config { protocol_version: 65, num_peers: 120, - })); + })) +} + +#[test] +fn rpc_net_version() { + let sync = sync_provider(); let net = NetClient::new(&sync).to_delegate(); let io = IoHandler::new(); io.add_delegate(net); @@ -37,10 +41,7 @@ fn rpc_net_version() { #[test] fn rpc_net_peer_count() { - let sync = Arc::new(TestSyncProvider::new(Config { - protocol_version: 65, - num_peers: 120, - })); + let sync = sync_provider(); let net = NetClient::new(&sync).to_delegate(); let io = IoHandler::new(); io.add_delegate(net); @@ -53,10 +54,7 @@ fn rpc_net_peer_count() { #[test] fn rpc_net_listening() { - let sync = Arc::new(TestSyncProvider::new(Config { - protocol_version: 65, - num_peers: 120, - })); + let sync = sync_provider(); let net = NetClient::new(&sync).to_delegate(); let io = IoHandler::new(); io.add_delegate(net); From a8a21da9ba7942615a6bbf031fc0ac78e9bc83f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 11 Mar 2016 11:05:20 +0100 Subject: [PATCH 07/12] Updating hook and removing running clippy from dev-dependencies --- Cargo.toml | 6 ------ hook.sh | 13 +++++++++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 22d0f9288..563dd2a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,6 @@ ethcore-devtools = { path = "devtools" } ethcore-rpc = { path = "rpc", optional = true } rpassword = "0.1" -[dev-dependencies] -ethcore = { path = "ethcore", features = ["dev"] } -ethcore-util = { path = "util", features = ["dev"] } -ethsync = { path = "sync", features = ["dev"] } -ethcore-rpc = { path = "rpc", features = ["dev"] } - [features] default = ["rpc"] rpc = ["ethcore-rpc"] diff --git a/hook.sh b/hook.sh index 354fddd5d..aa6ed7415 100755 --- a/hook.sh +++ b/hook.sh @@ -1,3 +1,12 @@ #!/bin/sh -echo "#!/bin/sh\ncargo test -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity --features dev-clippy" > ./.git/hooks/pre-push -chmod +x ./.git/hooks/pre-push +FILE=./.git/hooks/pre-push +echo "#!/bin/sh\n" > $FILE +# Exit on any error +echo "set -e" >> $FILE +# Run release build +echo "cargo build --release --features dev-clippy" >> $FILE +# Build tests +echo "cargo test --no-run --features dev-clippy \\" >> $FILE +echo " -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" >> $FILE +echo "" >> $FILE +chmod +x $FILE From d84e008e00b23d64d6bee1920cc545b434f5348d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 11 Mar 2016 11:16:49 +0100 Subject: [PATCH 08/12] Removing superflous check for nightly --- Cargo.toml | 5 ++--- cargo.sh | 2 -- ethcore/Cargo.toml | 6 +----- ethcore/build.rs | 25 ------------------------- ethcore/src/basic_types.rs | 2 +- ethcore/src/block.rs | 2 +- ethcore/src/block_queue.rs | 2 +- ethcore/src/blockchain/blockchain.rs | 4 ++-- ethcore/src/ethereum/ethash.rs | 2 +- ethcore/src/evm/interpreter.rs | 6 +++--- ethcore/src/externalities.rs | 2 +- ethcore/src/lib.rs | 10 +++++----- ethcore/src/service.rs | 2 +- ethcore/src/spec.rs | 2 +- ethcore/src/state.rs | 2 +- ethcore/src/transaction.rs | 2 +- hook.sh | 4 ++-- parity/main.rs | 6 +++--- rpc/Cargo.toml | 3 +-- rpc/build.rs | 7 ------- sync/Cargo.toml | 6 +----- sync/build.rs | 25 ------------------------- sync/src/chain.rs | 6 +++--- sync/src/lib.rs | 6 +++--- sync/src/range_collection.rs | 4 ++-- util/Cargo.toml | 3 +-- util/bigint/src/uint.rs | 6 +++--- util/build.rs | 5 ----- util/src/hash.rs | 4 ++-- util/src/lib.rs | 12 ++++++------ util/src/network/discovery.rs | 2 +- util/src/network/host.rs | 4 ++-- util/src/panics.rs | 2 +- util/src/trie/triedb.rs | 2 +- util/src/trie/triedbmut.rs | 4 ++-- 35 files changed, 56 insertions(+), 131 deletions(-) delete mode 100755 cargo.sh delete mode 100644 ethcore/build.rs delete mode 100644 sync/build.rs diff --git a/Cargo.toml b/Cargo.toml index 563dd2a69..4daabf669 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,10 +30,9 @@ rpassword = "0.1" [features] default = ["rpc"] rpc = ["ethcore-rpc"] -dev = ["ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev"] -dev-clippy = ["clippy", "ethcore/clippy", "ethcore-util/clippy", "ethsync/clippy", "ethcore-rpc/clippy"] +dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev"] travis-beta = ["ethcore/json-tests"] -travis-nightly = ["ethcore/json-tests", "dev-clippy", "dev"] +travis-nightly = ["ethcore/json-tests", "dev"] [[bin]] path = "parity/main.rs" diff --git a/cargo.sh b/cargo.sh deleted file mode 100755 index 6870ab385..000000000 --- a/cargo.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -cargo "$@" --features dev-clippy diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index fbfe175d7..c3a3d32dc 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -5,10 +5,6 @@ license = "GPL-3.0" name = "ethcore" version = "0.9.99" authors = ["Ethcore "] -build = "build.rs" - -[build-dependencies] -rustc_version = "0.1" [dependencies] log = "0.3" @@ -31,5 +27,5 @@ jit = ["evmjit"] evm-debug = [] json-tests = [] test-heavy = [] -dev = [] +dev = ["clippy"] default = [] diff --git a/ethcore/build.rs b/ethcore/build.rs deleted file mode 100644 index 41b9a1b3e..000000000 --- a/ethcore/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015, 2016 Ethcore (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 . - -extern crate rustc_version; - -use rustc_version::{version_meta, Channel}; - -fn main() { - if let Channel::Nightly = version_meta().channel { - println!("cargo:rustc-cfg=nightly"); - } -} diff --git a/ethcore/src/basic_types.rs b/ethcore/src/basic_types.rs index 9cba8b3a0..5f6515c0d 100644 --- a/ethcore/src/basic_types.rs +++ b/ethcore/src/basic_types.rs @@ -24,7 +24,7 @@ pub type LogBloom = H2048; /// Constant 2048-bit datum for 0. Often used as a default. pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); -#[cfg_attr(all(nightly, feature="dev"), allow(enum_variant_names))] +#[cfg_attr(feature="dev", allow(enum_variant_names))] /// Semantic boolean for when a seal/signature is included. pub enum Seal { /// The seal/signature is included. diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index b3894db94..9ecd58e0a 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -16,7 +16,7 @@ //! Blockchain block. -#![cfg_attr(all(nightly, feature="dev"), allow(ptr_arg))] // Because of &LastHashes -> &Vec<_> +#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_> use common::*; use engine::*; diff --git a/ethcore/src/block_queue.rs b/ethcore/src/block_queue.rs index 3dfb98e8a..c83542f12 100644 --- a/ethcore/src/block_queue.rs +++ b/ethcore/src/block_queue.rs @@ -121,7 +121,7 @@ struct QueueSignal { } impl QueueSignal { - #[cfg_attr(all(nightly, feature="dev"), allow(bool_comparison))] + #[cfg_attr(feature="dev", allow(bool_comparison))] fn set(&self) { if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false { self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message"); diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 8c21532c8..d67c1b7f1 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -891,7 +891,7 @@ mod tests { } #[test] - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn test_find_uncles() { let mut canon_chain = ChainGenerator::default(); let mut finalizer = BlockFinalizer::default(); @@ -929,7 +929,7 @@ mod tests { } #[test] - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn test_small_fork() { let mut canon_chain = ChainGenerator::default(); let mut finalizer = BlockFinalizer::default(); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index b0c0e4a9f..f9810b964 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -202,7 +202,7 @@ impl Engine for Ethash { } } -#[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] // to_ethash should take self +#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self impl Ethash { fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 { const EXP_DIFF_PERIOD: u64 = 100000; diff --git a/ethcore/src/evm/interpreter.rs b/ethcore/src/evm/interpreter.rs index fb8d19357..7491321cb 100644 --- a/ethcore/src/evm/interpreter.rs +++ b/ethcore/src/evm/interpreter.rs @@ -243,7 +243,7 @@ struct CodeReader<'a> { code: &'a Bytes } -#[cfg_attr(all(nightly, feature="dev"), allow(len_without_is_empty))] +#[cfg_attr(feature="dev", allow(len_without_is_empty))] impl<'a> CodeReader<'a> { /// Get `no_of_bytes` from code and convert to U256. Move PC fn read(&mut self, no_of_bytes: usize) -> U256 { @@ -258,7 +258,7 @@ impl<'a> CodeReader<'a> { } } -#[cfg_attr(all(nightly, feature="dev"), allow(enum_variant_names))] +#[cfg_attr(feature="dev", allow(enum_variant_names))] enum InstructionCost { Gas(U256), GasMem(U256, U256), @@ -347,7 +347,7 @@ impl evm::Evm for Interpreter { } impl Interpreter { - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn get_gas_cost_mem(&self, ext: &evm::Ext, instruction: Instruction, diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index a1f5763ea..598921580 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -188,7 +188,7 @@ impl<'a> Ext for Externalities<'a> { self.state.code(address).unwrap_or_else(|| vec![]) } - #[cfg_attr(all(nightly, feature="dev"), allow(match_ref_pats))] + #[cfg_attr(feature="dev", allow(match_ref_pats))] fn ret(&mut self, gas: &U256, data: &[u8]) -> Result { match &mut self.output { &mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 469364eb3..938da02a0 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -15,16 +15,16 @@ // along with Parity. If not, see . #![warn(missing_docs)] -#![cfg_attr(all(nightly, feature="dev"), feature(plugin))] -#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] +#![cfg_attr(feature="dev", feature(plugin))] +#![cfg_attr(feature="dev", plugin(clippy))] // Clippy config // TODO [todr] not really sure -#![cfg_attr(all(nightly, feature="dev"), allow(needless_range_loop))] +#![cfg_attr(feature="dev", allow(needless_range_loop))] // Shorter than if-else -#![cfg_attr(all(nightly, feature="dev"), allow(match_bool))] +#![cfg_attr(feature="dev", allow(match_bool))] // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. -#![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))] +#![cfg_attr(feature="dev", allow(clone_on_copy))] //! Ethcore library //! diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index bd15ee501..6daf0d7b6 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -117,7 +117,7 @@ impl IoHandler for ClientIoHandler { } } - #[cfg_attr(all(nightly, feature="dev"), allow(single_match))] + #[cfg_attr(feature="dev", allow(single_match))] fn message(&self, io: &IoContext, net_message: &NetSyncMessage) { if let UserMessage(ref message) = *net_message { match *message { diff --git a/ethcore/src/spec.rs b/ethcore/src/spec.rs index 774024351..2208350cc 100644 --- a/ethcore/src/spec.rs +++ b/ethcore/src/spec.rs @@ -99,7 +99,7 @@ pub struct Spec { genesis_state: PodState, } -#[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self) +#[cfg_attr(feature="dev", allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self) impl Spec { /// Convert this object into a boxed Engine of the right underlying type. // TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead. diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 7c1064abf..c13678c38 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -224,7 +224,7 @@ impl State { /// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit. /// `accounts` is mutable because we may need to commit the code or storage and record that. - #[cfg_attr(all(nightly, feature="dev"), allow(match_ref_pats))] + #[cfg_attr(feature="dev", allow(match_ref_pats))] pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap>) { // first, commit the sub trees. // TODO: is this necessary or can we dispense with the `ref mut a` for just `a`? diff --git a/ethcore/src/transaction.rs b/ethcore/src/transaction.rs index 733e5ac6b..a51824494 100644 --- a/ethcore/src/transaction.rs +++ b/ethcore/src/transaction.rs @@ -80,7 +80,7 @@ impl Transaction { } impl FromJson for SignedTransaction { - #[cfg_attr(all(nightly, feature="dev"), allow(single_char_pattern))] + #[cfg_attr(feature="dev", allow(single_char_pattern))] fn from_json(json: &Json) -> SignedTransaction { let t = Transaction { nonce: xjson!(&json["nonce"]), diff --git a/hook.sh b/hook.sh index aa6ed7415..9780541fe 100755 --- a/hook.sh +++ b/hook.sh @@ -4,9 +4,9 @@ echo "#!/bin/sh\n" > $FILE # Exit on any error echo "set -e" >> $FILE # Run release build -echo "cargo build --release --features dev-clippy" >> $FILE +echo "cargo build --release --features dev" >> $FILE # Build tests -echo "cargo test --no-run --features dev-clippy \\" >> $FILE +echo "cargo test --no-run --features dev \\" >> $FILE echo " -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" >> $FILE echo "" >> $FILE chmod +x $FILE diff --git a/parity/main.rs b/parity/main.rs index efff52e4e..c38c2d515 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -17,8 +17,8 @@ //! Ethcore client application. #![warn(missing_docs)] -#![cfg_attr(all(nightly, feature="dev"), feature(plugin))] -#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] +#![cfg_attr(feature="dev", feature(plugin))] +#![cfg_attr(feature="dev", plugin(clippy))] extern crate docopt; extern crate rustc_serialize; extern crate ethcore_util as util; @@ -293,7 +293,7 @@ impl Configuration { } } - #[cfg_attr(all(nightly, feature="dev"), allow(useless_format))] + #[cfg_attr(feature="dev", allow(useless_format))] fn net_addresses(&self) -> (Option, Option) { let mut listen_address = None; let mut public_address = None; diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 2ce430e51..f324aba10 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -26,9 +26,8 @@ serde_macros = { version = "0.7.0", optional = true } [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } syntex = "0.29.0" -rustc_version = "0.1" [features] default = ["serde_codegen"] nightly = ["serde_macros"] -dev = ["ethcore/dev", "ethcore-util/dev", "ethsync/dev"] +dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"] diff --git a/rpc/build.rs b/rpc/build.rs index 3806f6fe5..659bc35eb 100644 --- a/rpc/build.rs +++ b/rpc/build.rs @@ -14,10 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -extern crate rustc_version; - -use rustc_version::{version_meta, Channel}; - #[cfg(not(feature = "serde_macros"))] mod inner { extern crate syntex; @@ -46,7 +42,4 @@ mod inner { fn main() { inner::main(); - if let Channel::Nightly = version_meta().channel { - println!("cargo:rustc-cfg=nightly"); - } } diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 46baa8a83..0097cd47e 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -4,13 +4,9 @@ name = "ethsync" version = "0.9.99" license = "GPL-3.0" authors = ["Ethcore . - -extern crate rustc_version; - -use rustc_version::{version_meta, Channel}; - -fn main() { - if let Channel::Nightly = version_meta().channel { - println!("cargo:rustc-cfg=nightly"); - } -} diff --git a/sync/src/chain.rs b/sync/src/chain.rs index da3908a1e..7789fb004 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -275,7 +275,7 @@ impl ChainSync { } - #[cfg_attr(all(nightly, feature="dev"), allow(for_kv_map))] // Because it's not possible to get `values_mut()` + #[cfg_attr(feature="dev", allow(for_kv_map))] // Because it's not possible to get `values_mut()` /// Rest sync. Clear all downloaded data but keep the queue fn reset(&mut self) { self.downloading_headers.clear(); @@ -343,7 +343,7 @@ impl ChainSync { Ok(()) } - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] /// Called by peer once it has new block headers during sync fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders); @@ -470,7 +470,7 @@ impl ChainSync { } /// Called by peer once it has new block bodies - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { let block_rlp = try!(r.at(0)); let header_rlp = try!(block_rlp.at(0)); diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 3b79e5614..3ef4b4150 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -15,11 +15,11 @@ // along with Parity. If not, see . #![warn(missing_docs)] -#![cfg_attr(all(nightly, feature="dev"), feature(plugin))] -#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] +#![cfg_attr(feature="dev", feature(plugin))] +#![cfg_attr(feature="dev", plugin(clippy))] // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. -#![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))] +#![cfg_attr(feature="dev", allow(clone_on_copy))] //! Blockchain sync module //! Implements ethereum protocol version 63 as specified here: diff --git a/sync/src/range_collection.rs b/sync/src/range_collection.rs index 826a67121..664d7c7a3 100644 --- a/sync/src/range_collection.rs +++ b/sync/src/range_collection.rs @@ -42,7 +42,7 @@ pub trait RangeCollection { fn remove_head(&mut self, start: &K); /// Remove all elements >= `start` in the range that contains `start` fn remove_tail(&mut self, start: &K); - /// Remove all elements >= `start` + /// Remove all elements >= `start` fn remove_from(&mut self, start: &K); /// Remove all elements >= `tail` fn insert_item(&mut self, key: K, value: V); @@ -231,7 +231,7 @@ impl RangeCollection for Vec<(K, Vec)> where K: Ord + PartialEq + } #[test] -#[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] +#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn test_range() { use std::cmp::{Ordering}; diff --git a/util/Cargo.toml b/util/Cargo.toml index 0ce27ec2b..74e4d7226 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -40,8 +40,7 @@ chrono = "0.2" [features] default = [] -dev = [] +dev = ["clippy"] [build-dependencies] vergen = "*" -rustc_version = "0.1" diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 959df0944..32abdb5d5 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -1103,7 +1103,7 @@ macro_rules! construct_uint { } } - #[cfg_attr(all(nightly, feature="dev"), allow(derive_hash_xor_eq))] // We are pretty sure it's ok. + #[cfg_attr(feature="dev", allow(derive_hash_xor_eq))] // We are pretty sure it's ok. impl Hash for $name { fn hash(&self, state: &mut H) where H: Hasher { unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); } @@ -1485,7 +1485,7 @@ mod tests { } #[test] - #[cfg_attr(all(nightly, feature="dev"), allow(eq_op))] + #[cfg_attr(feature="dev", allow(eq_op))] pub fn uint256_comp_test() { let small = U256([10u64, 0, 0, 0]); let big = U256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]); @@ -2032,7 +2032,7 @@ mod tests { #[test] - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn u256_multi_full_mul() { let result = U256([0, 0, 0, 0]).full_mul(U256([0, 0, 0, 0])); assert_eq!(U512([0, 0, 0, 0, 0, 0, 0, 0]), result); diff --git a/util/build.rs b/util/build.rs index 0b9b233e0..b0b64a380 100644 --- a/util/build.rs +++ b/util/build.rs @@ -14,15 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -extern crate rustc_version; extern crate vergen; use vergen::*; -use rustc_version::{version_meta, Channel}; fn main() { vergen(OutputFns::all()).unwrap(); - if let Channel::Nightly = version_meta().channel { - println!("cargo:rustc-cfg=nightly"); - } } diff --git a/util/src/hash.rs b/util/src/hash.rs index 4eb96b53e..73fa33b47 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -305,7 +305,7 @@ macro_rules! impl_hash { } impl Copy for $from {} - #[cfg_attr(all(nightly, feature="dev"), allow(expl_impl_clone_on_copy))] + #[cfg_attr(feature="dev", allow(expl_impl_clone_on_copy))] impl Clone for $from { fn clone(&self) -> $from { unsafe { @@ -637,7 +637,7 @@ mod tests { use std::str::FromStr; #[test] - #[cfg_attr(all(nightly, feature="dev"), allow(eq_op))] + #[cfg_attr(feature="dev", allow(eq_op))] fn hash() { let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h); diff --git a/util/src/lib.rs b/util/src/lib.rs index 59d66a325..a50ba8da4 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -15,18 +15,18 @@ // along with Parity. If not, see . #![warn(missing_docs)] -#![cfg_attr(all(nightly, feature="dev"), feature(plugin))] -#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))] +#![cfg_attr(feature="dev", feature(plugin))] +#![cfg_attr(feature="dev", plugin(clippy))] // Clippy settings // TODO [todr] not really sure -#![cfg_attr(all(nightly, feature="dev"), allow(needless_range_loop))] +#![cfg_attr(feature="dev", allow(needless_range_loop))] // Shorter than if-else -#![cfg_attr(all(nightly, feature="dev"), allow(match_bool))] +#![cfg_attr(feature="dev", allow(match_bool))] // We use that to be more explicit about handled cases -#![cfg_attr(all(nightly, feature="dev"), allow(match_same_arms))] +#![cfg_attr(feature="dev", allow(match_same_arms))] // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. -#![cfg_attr(all(nightly, feature="dev"), allow(clone_on_copy))] +#![cfg_attr(feature="dev", allow(clone_on_copy))] //! Ethcore-util library //! diff --git a/util/src/network/discovery.rs b/util/src/network/discovery.rs index 644af22af..4f3384894 100644 --- a/util/src/network/discovery.rs +++ b/util/src/network/discovery.rs @@ -243,7 +243,7 @@ impl Discovery { self.send_to(packet, address.clone()); } - #[cfg_attr(all(nightly, feature="dev"), allow(map_clone))] + #[cfg_attr(feature="dev", allow(map_clone))] fn nearest_node_entries(target: &NodeId, buckets: &[NodeBucket]) -> Vec { let mut found: BTreeMap> = BTreeMap::new(); let mut count = 0; diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 2d1af55ba..ece24a1d1 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -507,7 +507,7 @@ impl Host where Message: Send + Sync + Clone { debug!(target: "network", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count()); } - #[cfg_attr(all(nightly, feature="dev"), allow(single_match))] + #[cfg_attr(feature="dev", allow(single_match))] fn connect_peer(&self, id: &NodeId, io: &IoContext>) { if self.have_session(id) { @@ -542,7 +542,7 @@ impl Host where Message: Send + Sync + Clone { self.create_connection(socket, Some(id), io); } - #[cfg_attr(all(nightly, feature="dev"), allow(block_in_if_condition_stmt))] + #[cfg_attr(feature="dev", allow(block_in_if_condition_stmt))] fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext>) { let nonce = self.info.write().unwrap().next_nonce(); let mut handshakes = self.handshakes.write().unwrap(); diff --git a/util/src/panics.rs b/util/src/panics.rs index 70ce0bc33..05d266b8b 100644 --- a/util/src/panics.rs +++ b/util/src/panics.rs @@ -71,7 +71,7 @@ impl PanicHandler { /// Invoke closure and catch any possible panics. /// In case of panic notifies all listeners about it. - #[cfg_attr(all(nightly, feature="dev"), allow(deprecated))] + #[cfg_attr(feature="dev", allow(deprecated))] pub fn catch_panic(&self, g: G) -> thread::Result where G: FnOnce() -> R + Send + 'static { let _guard = PanicGuard { handler: self }; let result = g(); diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index 182b87063..06076d273 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -54,7 +54,7 @@ pub struct TrieDB<'db> { pub hash_count: usize, } -#[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] +#[cfg_attr(feature="dev", allow(wrong_self_convention))] impl<'db> TrieDB<'db> { /// Create a new trie with the backing database `db` and `root` /// Panics, if `root` does not exist diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index 3d5c366e5..3d75fa3e1 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -66,7 +66,7 @@ enum MaybeChanged<'a> { Changed(Bytes), } -#[cfg_attr(all(nightly, feature="dev"), allow(wrong_self_convention))] +#[cfg_attr(feature="dev", allow(wrong_self_convention))] impl<'db> TrieDBMut<'db> { /// Create a new trie with the backing database `db` and empty `root` /// Initialise to the state entailed by the genesis block. @@ -350,7 +350,7 @@ impl<'db> TrieDBMut<'db> { } } - #[cfg_attr(all(nightly, feature="dev"), allow(cyclomatic_complexity))] + #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] /// Determine the RLP of the node, assuming we're inserting `partial` into the /// node currently of data `old`. This will *not* delete any hash of `old` from the database; /// it will just return the new RLP that includes the new node. From eb8e92c37f7ffca670c2c9790f3a585141ab6c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 11 Mar 2016 11:18:38 +0100 Subject: [PATCH 09/12] Cargo.lock --- Cargo.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f583a8747..627fbfa69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -219,7 +219,6 @@ dependencies = [ "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -243,7 +242,6 @@ dependencies = [ "jsonrpc-http-server 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -299,7 +297,6 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", ] From 68a13973a4c9e6151c77465d7798b68ed3fec75f Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 11:42:24 +0100 Subject: [PATCH 10/12] fixed ethcore-rpc tests build after merge --- rpc/src/v1/tests/helpers/sync_provider.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index b6d9241dd..a3711d949 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -40,6 +40,7 @@ impl TestSyncProvider { num_peers: config.num_peers, num_active_peers: 0, mem_used: 0, + transaction_queue_pending: 0, }, } } From 190630cc6bd3ed4d076f6b6490a431ee4b5180ec Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 12:31:45 +0100 Subject: [PATCH 11/12] separated transaction_request to its own submodule, added basic tests for it --- rpc/src/v1/impls/eth.rs | 3 +- rpc/src/v1/types/mod.rs.in | 3 +- rpc/src/v1/types/transaction.rs | 32 +------- rpc/src/v1/types/transaction_request.rs | 101 ++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 rpc/src/v1/types/transaction_request.rs diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 102d0da61..38e363624 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -27,6 +27,7 @@ use ethcore::block::{IsBlock}; use ethcore::views::*; use ethcore::ethereum::Ethash; use ethcore::ethereum::denominations::shannon; +use ethcore::transaction::Transaction as EthTransaction; use v1::traits::{Eth, EthFilter}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log}; use v1::helpers::{PollFilter, PollManager}; @@ -274,7 +275,7 @@ impl Eth for EthClient where C: BlockChainClient + 'static, S: match accounts.account_secret(&transaction_request.from) { Ok(secret) => { let sync = take_weak!(self.sync); - let (transaction, _) = transaction_request.to_eth(); + let transaction: EthTransaction = transaction_request.into(); let signed_transaction = transaction.sign(&secret); let hash = signed_transaction.hash(); sync.insert_transaction(signed_transaction); diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 2b2390ecb..ebc3bc0ff 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -23,6 +23,7 @@ mod log; mod optionals; mod sync; mod transaction; +mod transaction_request; pub use self::block::{Block, BlockTransactions}; pub use self::block_number::BlockNumber; @@ -33,5 +34,5 @@ pub use self::log::Log; pub use self::optionals::OptionalValue; pub use self::sync::{SyncStatus, SyncInfo}; pub use self::transaction::Transaction; -pub use self::transaction::TransactionRequest; +pub use self::transaction_request::TransactionRequest; diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 17b42cfcf..0518a58ea 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -17,8 +17,7 @@ use util::numbers::*; use ethcore::transaction::{LocalizedTransaction, Action}; use v1::types::{Bytes, OptionalValue}; -use serde::{Deserializer, Error}; -use ethcore; +use serde::Error; #[derive(Debug, Default, Serialize)] pub struct Transaction { @@ -39,35 +38,6 @@ pub struct Transaction { pub input: Bytes } -#[derive(Debug, Default, Serialize, Deserialize)] -pub struct TransactionRequest { - pub from: Address, - pub to: Option
, - #[serde(rename="gasPrice")] - pub gas_price: Option, - pub gas: Option, - pub value: Option, - pub data: Bytes, - pub nonce: Option, -} - -impl TransactionRequest { - /// maps transaction request to the transaction that can be signed and inserted - pub fn to_eth(self) -> (ethcore::transaction::Transaction, Address) { - (ethcore::transaction::Transaction { - nonce: self.nonce.unwrap_or(U256::zero()), - action: match self.to { - None => ethcore::transaction::Action::Create, - Some(addr) => ethcore::transaction::Action::Call(addr) - }, - gas: self.gas.unwrap_or(U256::zero()), - gas_price: self.gas_price.unwrap_or(U256::zero()), - value: self.value.unwrap_or(U256::zero()), - data: self.data.to_vec() - }, self.from) - } -} - impl From for Transaction { fn from(t: LocalizedTransaction) -> Transaction { Transaction { diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs new file mode 100644 index 000000000..a61b11c25 --- /dev/null +++ b/rpc/src/v1/types/transaction_request.rs @@ -0,0 +1,101 @@ +// Copyright 2015, 2016 Ethcore (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 . + +use util::hash::Address; +use util::numbers::{Uint, U256}; +use ethcore::transaction::{Action, Transaction}; +use v1::types::Bytes; + +#[derive(Debug, Default, Deserialize)] +pub struct TransactionRequest { + pub from: Address, + pub to: Option
, + #[serde(rename="gasPrice")] + pub gas_price: Option, + pub gas: Option, + pub value: Option, + pub data: Bytes, + pub nonce: Option, +} + +impl Into for TransactionRequest { + fn into(self) -> Transaction { + Transaction { + nonce: self.nonce.unwrap_or(U256::zero()), + action: match self.to { + None => Action::Create, + Some(addr) => Action::Call(addr) + }, + gas: self.gas.unwrap_or(U256::zero()), + gas_price: self.gas_price.unwrap_or(U256::zero()), + value: self.value.unwrap_or(U256::zero()), + data: self.data.to_vec() + } + } +} + +#[cfg(test)] +mod tests { + use util::numbers::{Uint, U256}; + use util::hash::Address; + use ethcore::transaction::{Transaction, Action}; + use v1::types::Bytes; + use super::*; + + #[test] + fn transaction_request_into_transaction() { + let tr = TransactionRequest { + from: Address::default(), + to: Some(Address::from(10)), + gas_price: Some(U256::from(20)), + gas: Some(U256::from(10_000)), + value: Some(U256::from(1)), + data: Bytes::new(vec![10, 20]), + nonce: Some(U256::from(12)), + }; + + assert_eq!(Transaction { + nonce: U256::from(12), + action: Action::Call(Address::from(10)), + gas: U256::from(10_000), + gas_price: U256::from(20), + value: U256::from(1), + data: vec![10, 20], + }, tr.into()); + } + + #[test] + fn empty_transaction_request_into_transaction() { + let tr = TransactionRequest { + from: Address::default(), + to: None, + gas_price: None, + gas: None, + value: None, + data: Bytes::new(vec![]), + nonce: None, + }; + + assert_eq!(Transaction { + nonce: U256::zero(), + action: Action::Create, + gas: U256::zero(), + gas_price: U256::zero(), + value: U256::zero(), + data: vec![], + }, tr.into()); + } +} From ecd33a60931be9616245984149a46aba12457f36 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 11 Mar 2016 13:54:52 +0100 Subject: [PATCH 12/12] fixed U256 and transaction request deserialization, added tests for transaction request --- rpc/src/v1/types/bytes.rs | 2 +- rpc/src/v1/types/transaction_request.rs | 64 ++++++++++++++++++++----- util/bigint/src/uint.rs | 8 +--- util/src/hash.rs | 2 +- 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/rpc/src/v1/types/bytes.rs b/rpc/src/v1/types/bytes.rs index 466fbebde..0b14c30e8 100644 --- a/rpc/src/v1/types/bytes.rs +++ b/rpc/src/v1/types/bytes.rs @@ -20,7 +20,7 @@ use serde::de::Visitor; use util::common::FromHex; /// Wrapper structure around vector of bytes. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Bytes(Vec); impl Bytes { diff --git a/rpc/src/v1/types/transaction_request.rs b/rpc/src/v1/types/transaction_request.rs index a61b11c25..d40402ab5 100644 --- a/rpc/src/v1/types/transaction_request.rs +++ b/rpc/src/v1/types/transaction_request.rs @@ -19,7 +19,7 @@ use util::numbers::{Uint, U256}; use ethcore::transaction::{Action, Transaction}; use v1::types::Bytes; -#[derive(Debug, Default, Deserialize)] +#[derive(Debug, Default, PartialEq, Deserialize)] pub struct TransactionRequest { pub from: Address, pub to: Option
, @@ -27,28 +27,26 @@ pub struct TransactionRequest { pub gas_price: Option, pub gas: Option, pub value: Option, - pub data: Bytes, + pub data: Option, pub nonce: Option, } impl Into for TransactionRequest { fn into(self) -> Transaction { Transaction { - nonce: self.nonce.unwrap_or(U256::zero()), - action: match self.to { - None => Action::Create, - Some(addr) => Action::Call(addr) - }, - gas: self.gas.unwrap_or(U256::zero()), - gas_price: self.gas_price.unwrap_or(U256::zero()), - value: self.value.unwrap_or(U256::zero()), - data: self.data.to_vec() + nonce: self.nonce.unwrap_or_else(U256::zero), + action: self.to.map_or(Action::Create, Action::Call), + gas: self.gas.unwrap_or_else(U256::zero), + gas_price: self.gas_price.unwrap_or_else(U256::zero), + value: self.value.unwrap_or_else(U256::zero), + data: self.data.map_or_else(Vec::new, |d| d.to_vec()), } } } #[cfg(test)] mod tests { + use serde_json; use util::numbers::{Uint, U256}; use util::hash::Address; use ethcore::transaction::{Transaction, Action}; @@ -63,7 +61,7 @@ mod tests { gas_price: Some(U256::from(20)), gas: Some(U256::from(10_000)), value: Some(U256::from(1)), - data: Bytes::new(vec![10, 20]), + data: Some(Bytes::new(vec![10, 20])), nonce: Some(U256::from(12)), }; @@ -85,7 +83,7 @@ mod tests { gas_price: None, gas: None, value: None, - data: Bytes::new(vec![]), + data: None, nonce: None, }; @@ -98,4 +96,44 @@ mod tests { data: vec![], }, tr.into()); } + + #[test] + fn transaction_request_deserialize() { + let s = r#"{ + "from":"0x0000000000000000000000000000000000000001", + "to":"0x0000000000000000000000000000000000000002", + "gasPrice":"0x1", + "gas":"0x2", + "value":"0x3", + "data":"0x123456", + "nonce":"0x4" + }"#; + let deserialized: TransactionRequest = serde_json::from_str(s).unwrap(); + + assert_eq!(deserialized, TransactionRequest { + from: Address::from(1), + to: Some(Address::from(2)), + gas_price: Some(U256::from(1)), + gas: Some(U256::from(2)), + value: Some(U256::from(3)), + data: Some(Bytes::new(vec![0x12, 0x34, 0x56])), + nonce: Some(U256::from(4)), + }); + } + + #[test] + fn transaction_request_deserialize_empty() { + let s = r#"{"from":"0x0000000000000000000000000000000000000001"}"#; + let deserialized: TransactionRequest = serde_json::from_str(s).unwrap(); + + assert_eq!(deserialized, TransactionRequest { + from: Address::from(1), + to: None, + gas_price: None, + gas: None, + value: None, + data: None, + nonce: None, + }); + } } diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 959df0944..47888fd88 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -39,7 +39,6 @@ use std::fmt; use std::cmp; -use std::mem; use std::str::{FromStr}; use std::convert::From; use std::hash::{Hash, Hasher}; @@ -788,14 +787,11 @@ macro_rules! construct_uint { fn visit_str(&mut self, value: &str) -> Result where E: serde::Error { // 0x + len - if value.len() != 2 + $n_words / 8 { + if value.len() > 2 + $n_words * 16 { return Err(serde::Error::custom("Invalid length.")); } - match $name::from_str(&value[2..]) { - Ok(val) => Ok(val), - Err(_) => { return Err(serde::Error::custom("Invalid length.")); } - } + $name::from_str(&value[2..]).map_err(|_| serde::Error::custom("Invalid hex value.")) } fn visit_string(&mut self, value: String) -> Result where E: serde::Error { diff --git a/util/src/hash.rs b/util/src/hash.rs index 4eb96b53e..3dc15116d 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -257,7 +257,7 @@ macro_rules! impl_hash { return Err(serde::Error::custom("Invalid length.")); } - value[2..].from_hex().map(|ref v| $from::from_slice(v)).map_err(|_| serde::Error::custom("Invalid valid hex.")) + value[2..].from_hex().map(|ref v| $from::from_slice(v)).map_err(|_| serde::Error::custom("Invalid hex value.")) } fn visit_string(&mut self, value: String) -> Result where E: serde::Error {