From 2f42e0eda0af6207d3d7d59b007af02256d88806 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 26 Jan 2016 19:24:33 +0100 Subject: [PATCH] parity on netstats --- rpc/Cargo.toml | 1 - rpc/src/impls/eth.rs | 20 ++++++++++++++------ rpc/src/lib.rs | 3 ++- rpc/src/traits/eth.rs | 1 + rpc/src/types/block.rs | 6 +++--- rpc/src/types/mod.rs | 17 +++++++++++++++++ util/Cargo.toml | 1 + util/src/hash.rs | 37 +++++++++++++++++++++++++++++++++++++ util/src/lib.rs | 1 + util/src/uint.rs | 13 +++++++++++++ 10 files changed, 89 insertions(+), 11 deletions(-) diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index d0f9f50e8..ccdd46679 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -8,7 +8,6 @@ authors = ["Marek Kotewicz , @@ -27,7 +28,7 @@ impl Eth for EthClient { fn author(&self, params: Params) -> Result { match params { - Params::None => Ok(Value::String(Address::new().to_hex())), + Params::None => Ok(as_value(&Address::new())), _ => Err(Error::invalid_params()) } } @@ -64,8 +65,15 @@ impl Eth for EthClient { Ok(Value::U64(0)) } - fn block(&self, _: Params) -> Result { - Ok(Value::Null) + fn block(&self, params: Params) -> Result { + if let Params::Array(ref arr) = params { + if let [ref h, Value::Bool(ref include_transactions)] = arr as &[Value] { + if let Ok(hash) = from_value::(h.clone()) { + return Ok(as_value(&Block::default())) + } + } + } + Err(Error::invalid_params()) } } @@ -91,6 +99,6 @@ impl EthFilter for EthFilterClient { } fn filter_changes(&self, _: Params) -> Result { - Ok(Value::Array(vec![Value::String(self.client.chain_info().best_block_hash.to_hex())])) + Ok(Value::Array(vec![as_value(&self.client.chain_info().best_block_hash)])) } } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 148e9f134..43a24a1fb 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -1,8 +1,9 @@ #![feature(custom_derive, custom_attribute, plugin)] +#![feature(slice_patterns)] #![plugin(serde_macros)] -extern crate rustc_serialize; extern crate serde; +extern crate serde_json; extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate ethcore_util as util; diff --git a/rpc/src/traits/eth.rs b/rpc/src/traits/eth.rs index 31e9df164..35b59a91c 100644 --- a/rpc/src/traits/eth.rs +++ b/rpc/src/traits/eth.rs @@ -35,6 +35,7 @@ pub trait Eth: Sized + Send + Sync + 'static { delegate.add_method("eth_coinbase", Eth::author); delegate.add_method("eth_gasPrice", Eth::gas_price); delegate.add_method("eth_blockNumber", Eth::block_number); + delegate.add_method("eth_getBlockByHash", Eth::block); delegate.add_method("eth_getBlockByNumber", Eth::block); delegate.add_method("eth_mining", Eth::is_mining); delegate.add_method("eth_hashrate", Eth::hashrate); diff --git a/rpc/src/types/block.rs b/rpc/src/types/block.rs index c15c8186d..7b23e2e0c 100644 --- a/rpc/src/types/block.rs +++ b/rpc/src/types/block.rs @@ -1,7 +1,7 @@ use util::hash::*; use util::uint::*; -#[derive(Default)] +#[derive(Default, Serialize)] pub struct Block { hash: H256, #[serde(rename="parentHash")] @@ -35,7 +35,7 @@ fn test_block_serialize() { use serde_json; let block = Block::default(); - //let serialized = serde_json::to_string(&block).unwrap(); - //println!("s: {:?}", serialized); + let serialized = serde_json::to_string(&block).unwrap(); + println!("s: {:?}", serialized); //assert!(false); } diff --git a/rpc/src/types/mod.rs b/rpc/src/types/mod.rs index fc9210db1..a2f1da63e 100644 --- a/rpc/src/types/mod.rs +++ b/rpc/src/types/mod.rs @@ -1 +1,18 @@ +use serde::{Serialize, Deserialize, de}; +use serde_json::value::{Value, Serializer, Deserializer}; + mod block; + +pub fn as_value(s: &S) -> Value where S: Serialize { + let mut serializer = Serializer::new(); + // should never panic! + s.serialize(&mut serializer).unwrap(); + serializer.unwrap() +} + +pub fn from_value(value: Value) -> Result::Error> where D: Deserialize { + let mut deserialier = Deserializer::new(value); + Deserialize::deserialize(&mut deserialier) +} + +pub use self::block::Block; diff --git a/util/Cargo.toml b/util/Cargo.toml index a91bff962..362db33b2 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -25,6 +25,7 @@ itertools = "0.4" crossbeam = "0.2" slab = { git = "https://github.com/arkpar/slab.git" } sha3 = { path = "sha3" } +serde = "0.6.7" clippy = "*" # Always newest, since we use nightly [dev-dependencies] diff --git a/util/src/hash.rs b/util/src/hash.rs index 0e4139f3c..011746028 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -8,6 +8,8 @@ use rand::os::OsRng; use bytes::{BytesConvertable,Populatable}; use from_json::*; use uint::{Uint, U256}; +use rustc_serialize::hex::ToHex; +use serde; /// Trait for a fixed-size byte array to be used as the output of hash functions. /// @@ -205,6 +207,41 @@ macro_rules! impl_hash { } } + impl serde::Serialize for $from { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: serde::Serializer { + let mut hex = "0x".to_owned(); + hex.push_str(self.to_hex().as_ref()); + serializer.visit_str(hex.as_ref()) + } + } + + impl serde::Deserialize for $from { + fn deserialize(deserializer: &mut D) -> Result<$from, D::Error> + where D: serde::Deserializer { + struct HashVisitor; + + impl serde::de::Visitor for HashVisitor { + type Value = $from; + + fn visit_str(&mut self, value: &str) -> Result where E: serde::Error { + // 0x + len + if value.len() != 2 + $size * 2 { + return Err(serde::Error::syntax("Invalid length.")); + } + + value[2..].from_hex().map(|ref v| $from::from_slice(v)).map_err(|_| serde::Error::syntax("Invalid valid hex.")) + } + + fn visit_string(&mut self, value: String) -> Result where E: serde::Error { + self.visit_str(value.as_ref()) + } + } + + deserializer.visit(HashVisitor) + } + } + impl FromJson for $from { fn from_json(json: &Json) -> Self { match *json { diff --git a/util/src/lib.rs b/util/src/lib.rs index 970c0713c..b1b93968c 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -55,6 +55,7 @@ extern crate secp256k1; extern crate arrayvec; extern crate elastic_array; extern crate crossbeam; +extern crate serde; /// TODO [Gav Wood] Please document me pub mod standard; diff --git a/util/src/uint.rs b/util/src/uint.rs index ab136d7c6..de05ca4a8 100644 --- a/util/src/uint.rs +++ b/util/src/uint.rs @@ -23,6 +23,8 @@ use standard::*; use from_json::*; +use rustc_serialize::hex::ToHex; +use serde; macro_rules! impl_map_from { ($thing:ident, $from:ty, $to:ty) => { @@ -436,6 +438,17 @@ macro_rules! construct_uint { } } + impl serde::Serialize for $name { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: serde::Serializer { + let mut hex = "0x".to_owned(); + let mut bytes = [0u8; 8 * $n_words]; + self.to_bytes(&mut bytes); + hex.push_str(bytes.to_hex().as_ref()); + serializer.visit_str(hex.as_ref()) + } + } + impl From for $name { fn from(value: u64) -> $name { let mut ret = [0; $n_words];