From 77bfe5ae0055ee8286e663f7433028d59d874188 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 29 Feb 2016 11:58:33 +0100 Subject: [PATCH] jsonrpc uses weak pointers to client --- parity/main.rs | 6 +++--- rpc/src/v1/impls/eth.rs | 43 +++++++++++++++++++++-------------------- rpc/src/v1/impls/mod.rs | 10 ++++++++++ rpc/src/v1/impls/net.rs | 12 ++++++------ 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 6415dfc33..3d0d183a3 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -148,9 +148,9 @@ fn setup_rpc_server(client: Arc, sync: Arc, url: &str, cors_dom let mut server = rpc::HttpServer::new(1); server.add_delegate(Web3Client::new().to_delegate()); - server.add_delegate(EthClient::new(client.clone(), sync.clone()).to_delegate()); - server.add_delegate(EthFilterClient::new(client).to_delegate()); - server.add_delegate(NetClient::new(sync).to_delegate()); + server.add_delegate(EthClient::new(&client, &sync).to_delegate()); + server.add_delegate(EthFilterClient::new(&client).to_delegate()); + server.add_delegate(NetClient::new(&sync).to_delegate()); server.start_async(url, cors_domain); } diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 689afd019..00bce5437 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . //! Eth rpc implementation. -use std::sync::Arc; +use std::sync::{Arc, Weak}; use ethsync::{EthSync, SyncState}; use jsonrpc_core::*; use util::hash::*; @@ -29,21 +29,22 @@ use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncIn /// Eth rpc implementation. pub struct EthClient { - client: Arc, - sync: Arc + client: Weak, + sync: Weak } impl EthClient { /// Creates new EthClient. - pub fn new(client: Arc, sync: Arc) -> Self { + pub fn new(client: &Arc, sync: &Arc) -> Self { EthClient { - client: client, - sync: sync + client: Arc::downgrade(client), + sync: Arc::downgrade(sync) } } fn block(&self, id: BlockId, include_txs: bool) -> Result { - 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(); @@ -78,9 +79,9 @@ impl EthClient { _ => Ok(Value::Null) } } - + fn transaction(&self, id: TransactionId) -> Result { - match self.client.transaction(id) { + match take_weak!(self.client).transaction(id) { Some(t) => to_value(&Transaction::from(t)), None => Ok(Value::Null) } @@ -90,7 +91,7 @@ impl EthClient { impl Eth for EthClient { fn protocol_version(&self, params: Params) -> Result { 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()) } } @@ -98,12 +99,12 @@ impl Eth for EthClient { fn syncing(&self, params: Params) -> Result { 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)) }) }; @@ -146,14 +147,14 @@ impl Eth for EthClient { fn block_number(&self, params: Params) -> Result { 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 { 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) }) @@ -161,7 +162,7 @@ impl Eth for EthClient { fn block_uncles_count(&self, params: Params) -> Result { 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) }) @@ -170,7 +171,7 @@ impl Eth for EthClient { // TODO: do not ignore block number param fn code_at(&self, params: Params) -> Result { 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 { @@ -201,7 +202,7 @@ impl Eth for EthClient { fn logs(&self, params: Params) -> Result { 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::>(); @@ -212,14 +213,14 @@ impl Eth for EthClient { /// Eth filter rpc implementation. pub struct EthFilterClient { - client: Arc + client: Weak } impl EthFilterClient { /// Creates new Eth filter client. - pub fn new(client: Arc) -> Self { + pub fn new(client: &Arc) -> Self { EthFilterClient { - client: client + client: Arc::downgrade(client) } } } @@ -234,6 +235,6 @@ impl EthFilter for EthFilterClient { } fn filter_changes(&self, _: Params) -> Result { - 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])) } } diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index bc8b436fd..d9102b1db 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -15,6 +15,16 @@ // along with Parity. If not, see . //! 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; diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index b36042dba..9e24caad2 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -15,31 +15,31 @@ // along with Parity. If not, see . //! 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 + sync: Weak } impl NetClient { /// Creates new NetClient. - pub fn new(sync: Arc) -> Self { + pub fn new(sync: &Arc) -> Self { NetClient { - sync: sync + sync: Arc::downgrade(sync) } } } impl Net for NetClient { fn version(&self, _: Params) -> Result { - 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 { - Ok(Value::U64(self.sync.status().num_peers as u64)) + Ok(Value::U64(take_weak!(self.sync).status().num_peers as u64)) } }