jsonrpc uses weak pointers to client

This commit is contained in:
debris 2016-02-29 11:58:33 +01:00
parent b1fc9bb342
commit 77bfe5ae00
4 changed files with 41 additions and 30 deletions

View File

@ -148,9 +148,9 @@ fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, url: &str, cors_dom
let mut server = rpc::HttpServer::new(1); let mut server = rpc::HttpServer::new(1);
server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(EthClient::new(client.clone(), sync.clone()).to_delegate()); server.add_delegate(EthClient::new(&client, &sync).to_delegate());
server.add_delegate(EthFilterClient::new(client).to_delegate()); server.add_delegate(EthFilterClient::new(&client).to_delegate());
server.add_delegate(NetClient::new(sync).to_delegate()); server.add_delegate(NetClient::new(&sync).to_delegate());
server.start_async(url, cors_domain); server.start_async(url, cors_domain);
} }

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Eth rpc implementation. //! Eth rpc implementation.
use std::sync::Arc; use std::sync::{Arc, Weak};
use ethsync::{EthSync, SyncState}; use ethsync::{EthSync, SyncState};
use jsonrpc_core::*; use jsonrpc_core::*;
use util::hash::*; use util::hash::*;
@ -29,21 +29,22 @@ use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncIn
/// Eth rpc implementation. /// Eth rpc implementation.
pub struct EthClient { pub struct EthClient {
client: Arc<Client>, client: Weak<Client>,
sync: Arc<EthSync> sync: Weak<EthSync>
} }
impl EthClient { impl EthClient {
/// Creates new 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 { EthClient {
client: client, client: Arc::downgrade(client),
sync: sync sync: Arc::downgrade(sync)
} }
} }
fn block(&self, id: BlockId, include_txs: bool) -> Result<Value, Error> { 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)) => { (Some(bytes), Some(total_difficulty)) => {
let block_view = BlockView::new(&bytes); let block_view = BlockView::new(&bytes);
let view = block_view.header_view(); let view = block_view.header_view();
@ -78,9 +79,9 @@ impl EthClient {
_ => Ok(Value::Null) _ => Ok(Value::Null)
} }
} }
fn transaction(&self, id: TransactionId) -> Result<Value, Error> { 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)), Some(t) => to_value(&Transaction::from(t)),
None => Ok(Value::Null) None => Ok(Value::Null)
} }
@ -90,7 +91,7 @@ impl EthClient {
impl Eth for EthClient { impl Eth for EthClient {
fn protocol_version(&self, params: Params) -> Result<Value, Error> { fn protocol_version(&self, params: Params) -> Result<Value, Error> {
match params { 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()) _ => Err(Error::invalid_params())
} }
} }
@ -98,12 +99,12 @@ impl Eth for EthClient {
fn syncing(&self, params: Params) -> Result<Value, Error> { fn syncing(&self, params: Params) -> Result<Value, Error> {
match params { match params {
Params::None => { Params::None => {
let status = self.sync.status(); let status = take_weak!(self.sync).status();
let res = match status.state { let res = match status.state {
SyncState::NotSynced | SyncState::Idle => SyncStatus::None, SyncState::NotSynced | SyncState::Idle => SyncStatus::None,
SyncState::Waiting | SyncState::Blocks | SyncState::NewBlocks => SyncStatus::Info(SyncInfo { SyncState::Waiting | SyncState::Blocks | SyncState::NewBlocks => SyncStatus::Info(SyncInfo {
starting_block: U256::from(status.start_block_number), 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)) highest_block: U256::from(status.highest_block_number.unwrap_or(status.start_block_number))
}) })
}; };
@ -146,14 +147,14 @@ impl Eth for EthClient {
fn block_number(&self, params: Params) -> Result<Value, Error> { fn block_number(&self, params: Params) -> Result<Value, Error> {
match params { 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()) _ => Err(Error::invalid_params())
} }
} }
fn block_transaction_count(&self, params: Params) -> Result<Value, Error> { fn block_transaction_count(&self, params: Params) -> Result<Value, Error> {
from_params::<(H256,)>(params) 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()), Some(bytes) => to_value(&BlockView::new(&bytes).transactions_count()),
None => Ok(Value::Null) None => Ok(Value::Null)
}) })
@ -161,7 +162,7 @@ impl Eth for EthClient {
fn block_uncles_count(&self, params: Params) -> Result<Value, Error> { fn block_uncles_count(&self, params: Params) -> Result<Value, Error> {
from_params::<(H256,)>(params) 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()), Some(bytes) => to_value(&BlockView::new(&bytes).uncles_count()),
None => Ok(Value::Null) None => Ok(Value::Null)
}) })
@ -170,7 +171,7 @@ impl Eth for EthClient {
// TODO: do not ignore block number param // TODO: do not ignore block number param
fn code_at(&self, params: Params) -> Result<Value, Error> { fn code_at(&self, params: Params) -> Result<Value, Error> {
from_params::<(Address, BlockNumber)>(params) 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> { fn block_by_hash(&self, params: Params) -> Result<Value, Error> {
@ -201,7 +202,7 @@ impl Eth for EthClient {
fn logs(&self, params: Params) -> Result<Value, Error> { fn logs(&self, params: Params) -> Result<Value, Error> {
from_params::<(Filter,)>(params) from_params::<(Filter,)>(params)
.and_then(|(filter,)| { .and_then(|(filter,)| {
let logs = self.client.logs(filter.into()) let logs = take_weak!(self.client).logs(filter.into())
.into_iter() .into_iter()
.map(From::from) .map(From::from)
.collect::<Vec<Log>>(); .collect::<Vec<Log>>();
@ -212,14 +213,14 @@ impl Eth for EthClient {
/// Eth filter rpc implementation. /// Eth filter rpc implementation.
pub struct EthFilterClient { pub struct EthFilterClient {
client: Arc<Client> client: Weak<Client>
} }
impl EthFilterClient { impl EthFilterClient {
/// Creates new Eth filter client. /// Creates new Eth filter client.
pub fn new(client: Arc<Client>) -> Self { pub fn new(client: &Arc<Client>) -> Self {
EthFilterClient { EthFilterClient {
client: client client: Arc::downgrade(client)
} }
} }
} }
@ -234,6 +235,6 @@ impl EthFilter for EthFilterClient {
} }
fn filter_changes(&self, _: Params) -> Result<Value, Error> { fn filter_changes(&self, _: Params) -> Result<Value, Error> {
to_value(&self.client.chain_info().best_block_hash).map(|v| Value::Array(vec![v])) to_value(&take_weak!(self.client).chain_info().best_block_hash).map(|v| Value::Array(vec![v]))
} }
} }

View File

@ -15,6 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethereum rpc interface implementation. //! 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 web3;
mod eth; mod eth;
mod net; mod net;

View File

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