Merge branch 'master' into rpc_poll_ids
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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![]),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user