Merge branch 'master' into rpc_poll_ids

This commit is contained in:
debris
2016-03-02 05:15:21 +01:00
74 changed files with 2584 additions and 851 deletions

View File

@@ -9,20 +9,20 @@ build = "build.rs"
[lib]
[dependencies]
serde = "0.6.7"
serde_json = "0.6.0"
jsonrpc-core = "1.1"
jsonrpc-http-server = "2.0"
serde = "0.7.0"
serde_json = "0.7.0"
jsonrpc-core = "1.2"
jsonrpc-http-server = "2.1"
ethcore-util = { path = "../util" }
ethcore = { path = "../ethcore" }
ethsync = { path = "../sync" }
clippy = { version = "0.0.44", optional = true }
rustc-serialize = "0.3"
serde_macros = { version = "0.6.13", optional = true }
transient-hashmap = "0.1"
serde_macros = { version = "0.7.0", optional = true }
[build-dependencies]
serde_codegen = { version = "0.6.13", optional = true }
serde_codegen = { version = "0.7.0", optional = true }
syntex = "0.29.0"
[features]

View File

@@ -16,8 +16,8 @@
//! Ethcore rpc.
#![warn(missing_docs)]
#![cfg_attr(nightly, feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(nightly, plugin(serde_macros, clippy))]
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
extern crate rustc_serialize;
extern crate serde;

View File

@@ -15,11 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Eth rpc implementation.
use std::sync::{Mutex, Arc};
use std::sync::{Arc, Weak, Mutex};
use ethsync::{EthSync, SyncState};
use jsonrpc_core::*;
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use util::sha3::*;
use ethcore::client::*;
use ethcore::views::*;
@@ -30,21 +29,22 @@ use v1::helpers::{PollFilter, PollIndexer};
/// Eth rpc implementation.
pub struct EthClient {
client: Arc<Client>,
sync: Arc<EthSync>
client: Weak<Client>,
sync: Weak<EthSync>
}
impl EthClient {
/// Creates new EthClient.
pub fn new(client: Arc<Client>, sync: Arc<EthSync>) -> Self {
pub fn new(client: &Arc<Client>, sync: &Arc<EthSync>) -> Self {
EthClient {
client: client,
sync: sync
client: Arc::downgrade(client),
sync: Arc::downgrade(sync)
}
}
fn block(&self, id: BlockId, include_txs: bool) -> Result<Value, Error> {
match (self.client.block(id.clone()), self.client.block_total_difficulty(id)) {
let client = take_weak!(self.client);
match (client.block(id.clone()), client.block_total_difficulty(id)) {
(Some(bytes), Some(total_difficulty)) => {
let block_view = BlockView::new(&bytes);
let view = block_view.header_view();
@@ -79,9 +79,9 @@ impl EthClient {
_ => Ok(Value::Null)
}
}
fn transaction(&self, id: TransactionId) -> Result<Value, Error> {
match self.client.transaction(id) {
match take_weak!(self.client).transaction(id) {
Some(t) => to_value(&Transaction::from(t)),
None => Ok(Value::Null)
}
@@ -91,7 +91,7 @@ impl EthClient {
impl Eth for EthClient {
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => to_value(&U256::from(self.sync.status().protocol_version)),
Params::None => to_value(&U256::from(take_weak!(self.sync).status().protocol_version)),
_ => Err(Error::invalid_params())
}
}
@@ -99,12 +99,12 @@ impl Eth for EthClient {
fn syncing(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => {
let status = self.sync.status();
let status = take_weak!(self.sync).status();
let res = match status.state {
SyncState::NotSynced | SyncState::Idle => SyncStatus::None,
SyncState::Waiting | SyncState::Blocks | SyncState::NewBlocks => SyncStatus::Info(SyncInfo {
starting_block: U256::from(status.start_block_number),
current_block: U256::from(self.client.chain_info().best_block_number),
current_block: U256::from(take_weak!(self.client).chain_info().best_block_number),
highest_block: U256::from(status.highest_block_number.unwrap_or(status.start_block_number))
})
};
@@ -147,14 +147,14 @@ impl Eth for EthClient {
fn block_number(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => to_value(&U256::from(self.client.chain_info().best_block_number)),
Params::None => to_value(&U256::from(take_weak!(self.client).chain_info().best_block_number)),
_ => Err(Error::invalid_params())
}
}
fn block_transaction_count(&self, params: Params) -> Result<Value, Error> {
from_params::<(H256,)>(params)
.and_then(|(hash,)| match self.client.block(BlockId::Hash(hash)) {
.and_then(|(hash,)| match take_weak!(self.client).block(BlockId::Hash(hash)) {
Some(bytes) => to_value(&BlockView::new(&bytes).transactions_count()),
None => Ok(Value::Null)
})
@@ -162,7 +162,7 @@ impl Eth for EthClient {
fn block_uncles_count(&self, params: Params) -> Result<Value, Error> {
from_params::<(H256,)>(params)
.and_then(|(hash,)| match self.client.block(BlockId::Hash(hash)) {
.and_then(|(hash,)| match take_weak!(self.client).block(BlockId::Hash(hash)) {
Some(bytes) => to_value(&BlockView::new(&bytes).uncles_count()),
None => Ok(Value::Null)
})
@@ -171,7 +171,7 @@ impl Eth for EthClient {
// TODO: do not ignore block number param
fn code_at(&self, params: Params) -> Result<Value, Error> {
from_params::<(Address, BlockNumber)>(params)
.and_then(|(address, _block_number)| to_value(&self.client.code(&address).map_or_else(Bytes::default, Bytes::new)))
.and_then(|(address, _block_number)| to_value(&take_weak!(self.client).code(&address).map_or_else(Bytes::default, Bytes::new)))
}
fn block_by_hash(&self, params: Params) -> Result<Value, Error> {
@@ -202,7 +202,7 @@ impl Eth for EthClient {
fn logs(&self, params: Params) -> Result<Value, Error> {
from_params::<(Filter,)>(params)
.and_then(|(filter,)| {
let logs = self.client.logs(filter.into())
let logs = take_weak!(self.client).logs(filter.into())
.into_iter()
.map(From::from)
.collect::<Vec<Log>>();
@@ -213,15 +213,15 @@ impl Eth for EthClient {
/// Eth filter rpc implementation.
pub struct EthFilterClient {
client: Arc<Client>,
polls: Mutex<PollIndexer<PollFilter>>
client: Weak<Client>,
polls: Mutex<PollIndexer<PollFilter>>,
}
impl EthFilterClient {
/// Creates new Eth filter client.
pub fn new(client: Arc<Client>) -> Self {
pub fn new(client: &Arc<Client>) -> Self {
EthFilterClient {
client: client,
client: Arc::downgrade(client),
polls: Mutex::new(PollIndexer::new())
}
}
@@ -232,7 +232,7 @@ impl EthFilter for EthFilterClient {
from_params::<(Filter,)>(params)
.and_then(|(filter,)| {
let mut polls = self.polls.lock().unwrap();
let id = polls.create_poll(PollFilter::Logs(filter.into()), self.client.chain_info().best_block_number);
let id = polls.create_poll(PollFilter::Logs(filter.into()), take_weak!(self.client).chain_info().best_block_number);
to_value(&U256::from(id))
})
}
@@ -241,7 +241,7 @@ impl EthFilter for EthFilterClient {
match params {
Params::None => {
let mut polls = self.polls.lock().unwrap();
let id = polls.create_poll(PollFilter::Block, self.client.chain_info().best_block_number);
let id = polls.create_poll(PollFilter::Block, take_weak!(self.client).chain_info().best_block_number);
to_value(&U256::from(id))
},
_ => Err(Error::invalid_params())
@@ -252,7 +252,7 @@ impl EthFilter for EthFilterClient {
match params {
Params::None => {
let mut polls = self.polls.lock().unwrap();
let id = polls.create_poll(PollFilter::PendingTransaction, self.client.chain_info().best_block_number);
let id = polls.create_poll(PollFilter::PendingTransaction, take_weak!(self.client).chain_info().best_block_number);
to_value(&U256::from(id))
},
_ => Err(Error::invalid_params())
@@ -260,6 +260,7 @@ impl EthFilter for EthFilterClient {
}
fn filter_changes(&self, params: Params) -> Result<Value, Error> {
let client = take_weak!(self.client);
from_params::<(Index,)>(params)
.and_then(|(index,)| {
let info = self.polls.lock().unwrap().get_poll(&index.value()).cloned();
@@ -267,10 +268,10 @@ impl EthFilter for EthFilterClient {
None => Ok(Value::Array(vec![] as Vec<Value>)),
Some(info) => match info.filter {
PollFilter::Block => {
let current_number = self.client.chain_info().best_block_number;
let current_number = client.chain_info().best_block_number;
let hashes = (info.block_number..current_number).into_iter()
.map(BlockId::Number)
.filter_map(|id| self.client.block_hash(id))
.filter_map(|id| client.block_hash(id))
.collect::<Vec<H256>>();
self.polls.lock().unwrap().update_poll(&index.value(), current_number);
@@ -279,17 +280,17 @@ impl EthFilter for EthFilterClient {
},
PollFilter::PendingTransaction => {
// TODO: fix implementation
to_value(&self.client.chain_info().best_block_hash).map(|v| Value::Array(vec![v]))
to_value(&client.chain_info().best_block_hash).map(|v| Value::Array(vec![v]))
},
PollFilter::Logs(mut filter) => {
filter.from_block = BlockId::Number(info.block_number);
filter.to_block = BlockId::Latest;
let logs = self.client.logs(filter)
let logs = client.logs(filter)
.into_iter()
.map(From::from)
.collect::<Vec<Log>>();
let current_number = self.client.chain_info().best_block_number;
let current_number = client.chain_info().best_block_number;
self.polls.lock().unwrap().update_poll(&index.value(), current_number);
to_value(&logs)

View File

@@ -15,6 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethereum rpc interface implementation.
macro_rules! take_weak {
($weak: expr) => {
match $weak.upgrade() {
Some(arc) => arc,
None => return Err(Error::internal_error())
}
}
}
mod web3;
mod eth;
mod net;

View File

@@ -15,31 +15,31 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Net rpc implementation.
use std::sync::Arc;
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use ethsync::EthSync;
use v1::traits::Net;
/// Net rpc implementation.
pub struct NetClient {
sync: Arc<EthSync>
sync: Weak<EthSync>
}
impl NetClient {
/// Creates new NetClient.
pub fn new(sync: Arc<EthSync>) -> Self {
pub fn new(sync: &Arc<EthSync>) -> Self {
NetClient {
sync: sync
sync: Arc::downgrade(sync)
}
}
}
impl Net for NetClient {
fn version(&self, _: Params) -> Result<Value, Error> {
Ok(Value::U64(self.sync.status().protocol_version as u64))
Ok(Value::U64(take_weak!(self.sync).status().protocol_version as u64))
}
fn peer_count(&self, _params: Params) -> Result<Value, Error> {
Ok(Value::U64(self.sync.status().num_peers as u64))
Ok(Value::U64(take_weak!(self.sync).status().num_peers as u64))
}
}

View File

@@ -15,8 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use serde::{Serialize, Serializer};
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use v1::types::{Bytes, Transaction, OptionalValue};
#[derive(Debug)]
@@ -71,8 +70,7 @@ pub struct Block {
#[cfg(test)]
mod tests {
use serde_json;
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use v1::types::{Transaction, Bytes, OptionalValue};
use super::*;

View File

@@ -30,7 +30,7 @@ pub enum BlockNumber {
impl Deserialize for BlockNumber {
fn deserialize<D>(deserializer: &mut D) -> Result<BlockNumber, D::Error>
where D: Deserializer {
deserializer.visit(BlockNumberVisitor)
deserializer.deserialize(BlockNumberVisitor)
}
}
@@ -44,8 +44,8 @@ impl Visitor for BlockNumberVisitor {
"latest" => Ok(BlockNumber::Latest),
"earliest" => Ok(BlockNumber::Earliest),
"pending" => Ok(BlockNumber::Pending),
_ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|_| Error::syntax("invalid block number")),
_ => value.parse::<u64>().map(BlockNumber::Num).map_err(|_| Error::syntax("invalid block number"))
_ if value.starts_with("0x") => u64::from_str_radix(&value[2..], 16).map(BlockNumber::Num).map_err(|_| Error::custom("invalid block number")),
_ => value.parse::<u64>().map(BlockNumber::Num).map_err(|_| Error::custom("invalid block number"))
}
}

View File

@@ -40,7 +40,7 @@ impl Serialize for Bytes {
where S: Serializer {
let mut serialized = "0x".to_owned();
serialized.push_str(self.0.to_hex().as_ref());
serializer.visit_str(serialized.as_ref())
serializer.serialize_str(serialized.as_ref())
}
}

View File

@@ -17,7 +17,7 @@
use serde::{Deserialize, Deserializer, Error};
use serde_json::value;
use jsonrpc_core::Value;
use util::hash::*;
use util::numbers::*;
use v1::types::BlockNumber;
use ethcore::filter::Filter as EthFilter;
use ethcore::client::BlockId;
@@ -40,7 +40,7 @@ impl<T> Deserialize for VariadicValue<T> where T: Deserialize {
Deserialize::deserialize(&mut value::Deserializer::new(v.clone())).map(VariadicValue::Single)
.or_else(|_| Deserialize::deserialize(&mut value::Deserializer::new(v.clone())).map(VariadicValue::Multiple))
.map_err(|_| Error::syntax("")) // unreachable, but types must match
.map_err(|_| Error::custom("")) // unreachable, but types must match
}
}
@@ -48,6 +48,7 @@ pub type FilterAddress = VariadicValue<Address>;
pub type Topic = VariadicValue<H256>;
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Filter {
#[serde(rename="fromBlock")]
pub from_block: Option<BlockNumber>,

View File

@@ -30,7 +30,7 @@ impl Index {
impl Deserialize for Index {
fn deserialize<D>(deserializer: &mut D) -> Result<Index, D::Error>
where D: Deserializer {
deserializer.visit(IndexVisitor)
deserializer.deserialize(IndexVisitor)
}
}
@@ -41,8 +41,8 @@ impl Visitor for IndexVisitor {
fn visit_str<E>(&mut self, value: &str) -> Result<Self::Value, E> where E: Error {
match value {
_ if value.starts_with("0x") => usize::from_str_radix(&value[2..], 16).map(Index).map_err(|_| Error::syntax("invalid index")),
_ => value.parse::<usize>().map(Index).map_err(|_| Error::syntax("invalid index"))
_ if value.starts_with("0x") => usize::from_str_radix(&value[2..], 16).map(Index).map_err(|_| Error::custom("invalid index")),
_ => value.parse::<usize>().map(Index).map_err(|_| Error::custom("invalid index"))
}
}

View File

@@ -14,8 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use ethcore::log_entry::LocalizedLogEntry;
use v1::types::Bytes;
@@ -55,8 +54,7 @@ impl From<LocalizedLogEntry> for Log {
mod tests {
use serde_json;
use std::str::FromStr;
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use v1::types::{Bytes, Log};
#[test]
@@ -66,7 +64,7 @@ mod tests {
let log = Log {
address: Address::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
topics: vec![
H256::from_str("a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc").unwrap(),
H256::from_str("a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc").unwrap(),
H256::from_str("4861736852656700000000000000000000000000000000000000000000000000").unwrap()
],
data: Bytes::new(vec![]),

View File

@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use serde::{Serialize, Serializer};
use util::uint::*;
use util::numbers::*;
#[derive(Default, Debug, Serialize, PartialEq)]
pub struct SyncInfo {

View File

@@ -14,8 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::hash::*;
use util::uint::*;
use util::numbers::*;
use ethcore::transaction::{LocalizedTransaction, Action};
use v1::types::{Bytes, OptionalValue};