Silent running operating modes (#1477)

* Command=line options.

* Keep alive for the eth protocol.

* Wire up final pieces.

* No network when dark.

* Passive and dark mode work.

* Ensure all RPCs keep alive.

* Fix tests.

* Fix minor bug.

* Minor whitespace.

* Split out some of the sleep-state.

* Fix help text.
This commit is contained in:
Gav Wood
2016-07-05 17:50:46 +02:00
committed by GitHub
parent 62b9c1b14f
commit c26cfc1c5a
16 changed files with 326 additions and 24 deletions

View File

@@ -241,6 +241,19 @@ fn no_author_err() -> Error {
}
}
impl<C, S, M, EM> EthClient<C, S, M, EM> where
C: MiningBlockChainClient + 'static,
S: SyncProvider + 'static,
M: MinerService + 'static,
EM: ExternalMinerService + 'static {
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
C: MiningBlockChainClient + 'static,
S: SyncProvider + 'static,
@@ -248,6 +261,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
EM: ExternalMinerService + 'static {
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => Ok(Value::String(format!("{}", take_weak!(self.sync).status().protocol_version).to_owned())),
_ => Err(Error::invalid_params())
@@ -255,6 +269,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn syncing(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => {
let status = take_weak!(self.sync).status();
@@ -281,6 +296,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn author(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&take_weak!(self.miner).author()),
_ => Err(Error::invalid_params()),
@@ -288,6 +304,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn is_mining(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&self.external_miner.is_mining()),
_ => Err(Error::invalid_params())
@@ -295,6 +312,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn hashrate(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&self.external_miner.hashrate()),
_ => Err(Error::invalid_params())
@@ -302,6 +320,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn gas_price(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => {
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
@@ -312,11 +331,13 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn accounts(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
to_value(&store.accounts())
}
fn block_number(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&U256::from(take_weak!(self.client).chain_info().best_block_number)),
_ => Err(Error::invalid_params())
@@ -324,6 +345,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn balance(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params_default_second(params)
.and_then(|(address, block_number,)| match block_number {
BlockNumber::Pending => to_value(&take_weak!(self.miner).balance(take_weak!(self.client).deref(), &address)),
@@ -332,6 +354,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn storage_at(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params_default_third::<Address, U256>(params)
.and_then(|(address, position, block_number,)| match block_number {
BlockNumber::Pending => to_value(&U256::from(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)))),
@@ -343,6 +366,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn transaction_count(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params_default_second(params)
.and_then(|(address, block_number,)| match block_number {
BlockNumber::Pending => to_value(&take_weak!(self.miner).nonce(take_weak!(self.client).deref(), &address)),
@@ -351,6 +375,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn block_transaction_count_by_hash(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256,)>(params)
.and_then(|(hash,)| // match
take_weak!(self.client).block(BlockID::Hash(hash))
@@ -358,6 +383,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn block_transaction_count_by_number(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber,)>(params)
.and_then(|(block_number,)| match block_number {
BlockNumber::Pending => to_value(
@@ -369,6 +395,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn block_uncles_count_by_hash(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256,)>(params)
.and_then(|(hash,)|
take_weak!(self.client).block(BlockID::Hash(hash))
@@ -376,6 +403,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn block_uncles_count_by_number(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber,)>(params)
.and_then(|(block_number,)| match block_number {
BlockNumber::Pending => to_value(&U256::from(0)),
@@ -385,6 +413,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn code_at(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params_default_second(params)
.and_then(|(address, block_number,)| match block_number {
BlockNumber::Pending => to_value(&take_weak!(self.miner).code(take_weak!(self.client).deref(), &address).map_or_else(Bytes::default, Bytes::new)),
@@ -394,16 +423,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn block_by_hash(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256, bool)>(params)
.and_then(|(hash, include_txs)| self.block(BlockID::Hash(hash), include_txs))
}
fn block_by_number(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber, bool)>(params)
.and_then(|(number, include_txs)| self.block(number.into(), include_txs))
}
fn transaction_by_hash(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256,)>(params)
.and_then(|(hash,)| {
let miner = take_weak!(self.miner);
@@ -415,16 +447,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn transaction_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256, Index)>(params)
.and_then(|(hash, index)| self.transaction(TransactionID::Location(BlockID::Hash(hash), index.value())))
}
fn transaction_by_block_number_and_index(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber, Index)>(params)
.and_then(|(number, index)| self.transaction(TransactionID::Location(number.into(), index.value())))
}
fn transaction_receipt(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256,)>(params)
.and_then(|(hash,)| {
let miner = take_weak!(self.miner);
@@ -440,16 +475,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn uncle_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256, Index)>(params)
.and_then(|(hash, index)| self.uncle(UncleID { block: BlockID::Hash(hash), position: index.value() }))
}
fn uncle_by_block_number_and_index(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber, Index)>(params)
.and_then(|(number, index)| self.uncle(UncleID { block: number.into(), position: index.value() }))
}
fn compilers(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&vec![] as &Vec<String>),
_ => Err(Error::invalid_params())
@@ -457,6 +495,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn logs(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Filter,)>(params)
.and_then(|(filter,)| {
let include_pending = filter.to_block == Some(BlockNumber::Pending);
@@ -476,6 +515,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn work(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => {
let client = take_weak!(self.client);
@@ -512,6 +552,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn submit_work(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H64, H256, H256)>(params).and_then(|(nonce, pow_hash, mix_hash)| {
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
let miner = take_weak!(self.miner);
@@ -523,6 +564,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn submit_hashrate(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256, H256)>(params).and_then(|(rate, id)| {
self.external_miner.submit_hashrate(rate, id);
to_value(&true)
@@ -530,6 +572,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn send_raw_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Bytes, )>(params)
.and_then(|(raw_transaction, )| {
let raw_transaction = raw_transaction.to_vec();
@@ -541,6 +584,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn call(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
trace!(target: "jsonrpc", "call: {:?}", params);
from_params_default_second(params)
.and_then(|(request, block_number,)| {
@@ -555,6 +599,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn estimate_gas(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params_default_second(params)
.and_then(|(request, block_number,)| {
let signed = try!(self.sign_call(request));
@@ -568,14 +613,17 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
}
fn compile_lll(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
rpc_unimplemented!()
}
fn compile_serpent(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
rpc_unimplemented!()
}
fn compile_solidity(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
rpc_unimplemented!()
}
}

View File

@@ -52,6 +52,12 @@ impl<C, M> EthFilterClient<C, M> where
polls: Mutex::new(PollManager::new()),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> EthFilter for EthFilterClient<C, M> where
@@ -59,6 +65,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
M: MinerService + 'static {
fn new_filter(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Filter,)>(params)
.and_then(|(filter,)| {
let mut polls = self.polls.lock().unwrap();
@@ -69,6 +76,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}
fn new_block_filter(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => {
let mut polls = self.polls.lock().unwrap();
@@ -80,6 +88,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}
fn new_pending_transaction_filter(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => {
let mut polls = self.polls.lock().unwrap();
@@ -93,6 +102,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}
fn filter_changes(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
let client = take_weak!(self.client);
from_params::<(Index,)>(params)
.and_then(|(index,)| {
@@ -181,6 +191,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}
fn filter_logs(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Index,)>(params)
.and_then(|(index,)| {
let mut polls = self.polls.lock().unwrap();
@@ -206,6 +217,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}
fn uninstall_filter(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Index,)>(params)
.and_then(|(index,)| {
self.polls.lock().unwrap().remove_poll(&index.value());

View File

@@ -61,6 +61,12 @@ impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: Miner
miner: Arc::downgrade(miner),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> EthSigning for EthSigningQueueClient<C, M>
@@ -68,12 +74,14 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
{
fn sign(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
warn!("Invoking eth_sign is not yet supported with signer enabled.");
// TODO [ToDr] Implement sign when rest of the signing queue is ready.
rpc_unimplemented!()
}
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(TransactionRequest, )>(params)
.and_then(|(mut request, )| {
let accounts = take_weak!(self.accounts);
@@ -118,6 +126,12 @@ impl<C, M> EthSigningUnsafeClient<C, M> where
accounts: Arc::downgrade(accounts),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
@@ -125,12 +139,14 @@ impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
M: MinerService + 'static {
fn sign(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Address, H256)>(params).and_then(|(addr, msg)| {
to_value(&take_weak!(self.accounts).sign(addr, msg).unwrap_or(H520::zero()))
})
}
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(TransactionRequest, )>(params)
.and_then(|(request, )| {
let sender = request.from;

View File

@@ -52,56 +52,74 @@ impl<C, M> EthcoreClient<C, M> where C: MiningBlockChainClient, M: MinerService
confirmations_queue: queue,
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: MiningBlockChainClient + 'static {
fn transactions_limit(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&take_weak!(self.miner).transactions_limit())
}
fn min_gas_price(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&take_weak!(self.miner).minimal_gas_price())
}
fn extra_data(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&Bytes::new(take_weak!(self.miner).extra_data()))
}
fn gas_floor_target(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&take_weak!(self.miner).gas_floor_target())
}
fn gas_ceil_target(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&take_weak!(self.miner).gas_ceil_target())
}
fn dev_logs(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
let logs = self.logger.logs();
to_value(&logs.deref().as_slice())
}
fn dev_logs_levels(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&self.logger.levels())
}
fn net_chain(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&self.settings.chain)
}
fn net_max_peers(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&self.settings.max_peers)
}
fn net_port(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&self.settings.network_port)
}
fn node_name(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
to_value(&self.settings.name)
}
fn rpc_settings(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
let mut map = BTreeMap::new();
map.insert("enabled".to_owned(), Value::Bool(self.settings.rpc_enabled));
map.insert("interface".to_owned(), Value::String(self.settings.rpc_interface.clone()));
@@ -110,6 +128,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
}
fn default_extra_data(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => to_value(&Bytes::new(version_data())),
_ => Err(Error::invalid_params()),
@@ -117,6 +136,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
}
fn gas_price_statistics(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
match params {
Params::None => match take_weak!(self.client).gas_price_statistics(100, 8) {
Ok(stats) => to_value(&stats
@@ -130,6 +150,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
}
fn unsigned_transactions_count(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
match self.confirmations_queue {
None => Err(Error {
code: ErrorCode::ServerError(error_codes::SIGNER_DISABLED),

View File

@@ -20,31 +20,46 @@ use util::network::{NetworkService, NonReservedPeerMode};
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use ethcore::service::SyncMessage;
use v1::traits::EthcoreSet;
use v1::types::Bytes;
/// Ethcore-specific rpc interface for operations altering the settings.
pub struct EthcoreSetClient<M> where
pub struct EthcoreSetClient<C, M> where
C: MiningBlockChainClient,
M: MinerService {
client: Weak<C>,
miner: Weak<M>,
net: Weak<NetworkService<SyncMessage>>,
}
impl<M> EthcoreSetClient<M> where M: MinerService {
impl<C, M> EthcoreSetClient<C, M> where
C: MiningBlockChainClient,
M: MinerService {
/// Creates new `EthcoreSetClient`.
pub fn new(miner: &Arc<M>, net: &Arc<NetworkService<SyncMessage>>) -> Self {
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<NetworkService<SyncMessage>>) -> Self {
EthcoreSetClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
net: Arc::downgrade(net),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
C: MiningBlockChainClient + 'static,
M: MinerService + 'static {
fn set_min_gas_price(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(gas_price,)| {
take_weak!(self.miner).set_minimal_gas_price(gas_price);
to_value(&true)
@@ -52,6 +67,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_gas_floor_target(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_floor_target(target);
to_value(&true)
@@ -59,6 +75,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_gas_ceil_target(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_ceil_target(target);
to_value(&true)
@@ -66,6 +83,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_extra_data(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Bytes,)>(params).and_then(|(extra_data,)| {
take_weak!(self.miner).set_extra_data(extra_data.to_vec());
to_value(&true)
@@ -73,6 +91,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_author(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Address,)>(params).and_then(|(author,)| {
take_weak!(self.miner).set_author(author);
to_value(&true)
@@ -80,6 +99,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_transactions_limit(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(usize,)>(params).and_then(|(limit,)| {
take_weak!(self.miner).set_transactions_limit(limit);
to_value(&true)
@@ -87,6 +107,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn set_tx_gas_limit(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(limit,)| {
take_weak!(self.miner).set_tx_gas_limit(limit.into());
to_value(&true)
@@ -94,6 +115,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn add_reserved_peer(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(String,)>(params).and_then(|(peer,)| {
match take_weak!(self.net).add_reserved_peer(&peer) {
Ok(()) => to_value(&true),
@@ -103,6 +125,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn remove_reserved_peer(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(String,)>(params).and_then(|(peer,)| {
match take_weak!(self.net).remove_reserved_peer(&peer) {
Ok(()) => to_value(&true),
@@ -112,11 +135,13 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}
fn drop_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Deny);
to_value(&true)
}
fn accept_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Accept);
to_value(&true)
}

View File

@@ -43,22 +43,31 @@ impl<C, M> PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService
signer_port: signer_port,
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn signer_enabled(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
self.signer_port
.map(|v| to_value(&v))
.unwrap_or_else(|| to_value(&false))
}
fn accounts(&self, _: Params) -> Result<Value, Error> {
try!(self.active());
let store = take_weak!(self.accounts);
to_value(&store.accounts())
}
fn new_account(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(String, )>(params).and_then(
|(pass, )| {
let store = take_weak!(self.accounts);
@@ -71,6 +80,7 @@ impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBl
}
fn unlock_account(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(Address, String, u64)>(params).and_then(
|(account, account_pass, _)|{
let store = take_weak!(self.accounts);
@@ -82,6 +92,7 @@ impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBl
}
fn sign_and_send_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(TransactionRequest, String)>(params)
.and_then(|(request, password)| {
let sender = request.from;

View File

@@ -46,16 +46,24 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
miner: Arc::downgrade(miner),
}
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
fn transactions_to_confirm(&self, _params: Params) -> Result<Value, Error> {
try!(self.active());
let queue = take_weak!(self.queue);
to_value(&queue.requests())
}
fn confirm_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256, TransactionModification, String)>(params).and_then(
|(id, modification, pass)| {
let accounts = take_weak!(self.accounts);
@@ -87,6 +95,7 @@ impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: Mini
}
fn reject_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(U256, )>(params).and_then(
|(id, )| {
let queue = take_weak!(self.queue);

View File

@@ -55,10 +55,17 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
}.fake_sign(from))
}
fn active(&self) -> Result<(), Error> {
// TODO: only call every 30s at most.
take_weak!(self.client).keep_alive();
Ok(())
}
}
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
fn filter(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(TraceFilter,)>(params)
.and_then(|(filter, )| {
let client = take_weak!(self.client);
@@ -69,6 +76,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
}
fn block_traces(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(BlockNumber,)>(params)
.and_then(|(block_number,)| {
let client = take_weak!(self.client);
@@ -79,6 +87,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
}
fn transaction_traces(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256,)>(params)
.and_then(|(transaction_hash,)| {
let client = take_weak!(self.client);
@@ -89,6 +98,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
}
fn trace(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256, Vec<Index>)>(params)
.and_then(|(transaction_hash, address)| {
let client = take_weak!(self.client);
@@ -103,6 +113,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
}
fn call(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
trace!(target: "jsonrpc", "call: {:?}", params);
from_params(params)
.and_then(|(request, flags)| {

View File

@@ -20,6 +20,7 @@ use jsonrpc_core::IoHandler;
use v1::{EthcoreSet, EthcoreSetClient};
use ethcore::miner::MinerService;
use ethcore::service::SyncMessage;
use ethcore::client::TestBlockChainClient;
use v1::tests::helpers::TestMinerService;
use util::numbers::*;
use util::network::{NetworkConfiguration, NetworkService};
@@ -29,20 +30,25 @@ fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService::default())
}
fn client_service() -> Arc<TestBlockChainClient> {
Arc::new(TestBlockChainClient::default())
}
fn network_service() -> Arc<NetworkService<SyncMessage>> {
Arc::new(NetworkService::new(NetworkConfiguration::new()).unwrap())
}
fn ethcore_set_client(miner: &Arc<TestMinerService>, net: &Arc<NetworkService<SyncMessage>>) -> EthcoreSetClient<TestMinerService> {
EthcoreSetClient::new(miner, net)
fn ethcore_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<NetworkService<SyncMessage>>) -> EthcoreSetClient<TestBlockChainClient, TestMinerService> {
EthcoreSetClient::new(client, miner, net)
}
#[test]
fn rpc_ethcore_set_min_gas_price() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@@ -50,12 +56,14 @@ fn rpc_ethcore_set_min_gas_price() {
assert_eq!(io.handle_request(request), Some(response.to_owned()));
assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
}
#[test]
fn rpc_ethcore_set_gas_floor_target() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@@ -67,9 +75,10 @@ fn rpc_ethcore_set_gas_floor_target() {
#[test]
fn rpc_ethcore_set_extra_data() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@@ -81,9 +90,10 @@ fn rpc_ethcore_set_extra_data() {
#[test]
fn rpc_ethcore_set_author() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@@ -95,9 +105,10 @@ fn rpc_ethcore_set_author() {
#[test]
fn rpc_ethcore_set_transactions_limit() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let io = IoHandler::new();
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;